@@ -7,7 +7,8 @@ import androidx.annotation.DrawableRes
7
7
import androidx.compose.foundation.Image
8
8
import androidx.compose.foundation.layout.Box
9
9
import androidx.compose.runtime.Composable
10
- import androidx.compose.runtime.collectAsState
10
+ import androidx.compose.runtime.MutableState
11
+ import androidx.compose.runtime.mutableStateOf
11
12
import androidx.compose.runtime.remember
12
13
import androidx.compose.ui.Alignment
13
14
import androidx.compose.ui.Modifier
@@ -20,21 +21,12 @@ import androidx.compose.ui.graphics.painter.ColorPainter
20
21
import androidx.compose.ui.graphics.painter.Painter
21
22
import androidx.compose.ui.layout.ContentScale
22
23
import androidx.compose.ui.layout.Layout
23
- import androidx.compose.ui.layout.layout
24
24
import androidx.compose.ui.platform.LocalContext
25
25
import androidx.compose.ui.platform.LocalInspectionMode
26
26
import com.bumptech.glide.Glide
27
27
import com.bumptech.glide.RequestBuilder
28
28
import com.bumptech.glide.RequestManager
29
- import com.bumptech.glide.integration.ktx.AsyncGlideSize
30
- import com.bumptech.glide.integration.ktx.ExperimentGlideFlows
31
- import com.bumptech.glide.integration.ktx.GlideFlowInstant
32
- import com.bumptech.glide.integration.ktx.ImmediateGlideSize
33
29
import com.bumptech.glide.integration.ktx.InternalGlideApi
34
- import com.bumptech.glide.integration.ktx.ResolvableGlideSize
35
- import com.bumptech.glide.integration.ktx.Resource
36
- import com.bumptech.glide.integration.ktx.Status
37
- import com.bumptech.glide.integration.ktx.flowResolvable
38
30
import com.bumptech.glide.load.DataSource
39
31
import com.google.accompanist.drawablepainter.DrawablePainter
40
32
import com.google.accompanist.drawablepainter.rememberDrawablePainter
@@ -90,7 +82,6 @@ public typealias RequestBuilderTransform<T> = (RequestBuilder<T>) -> RequestBuil
90
82
// to RequestBuilder (though thumbnail() may make that a challenge).
91
83
// TODO(judds): Consider how to deal with transitions.
92
84
@ExperimentalGlideComposeApi
93
- @OptIn(InternalGlideApi ::class )
94
85
@Composable
95
86
public fun GlideImage (
96
87
model : Any? ,
@@ -144,16 +135,16 @@ public fun GlideImage(
144
135
}
145
136
}
146
137
} else {
147
- val size : ImmediateGlideSize ? = requestBuilder.overrideSize()?. let { ImmediateGlideSize (it) }
148
- ModifierGlideImage (
149
- requestBuilder,
150
- size ,
151
- contentDescription,
152
- modifier ,
153
- alignment ,
154
- contentScale ,
155
- alpha ,
156
- colorFilter,
138
+ SimpleLayout (
139
+ modifier
140
+ .glideNode(
141
+ requestBuilder ,
142
+ contentDescription,
143
+ alignment ,
144
+ contentScale ,
145
+ alpha ,
146
+ colorFilter ,
147
+ )
157
148
)
158
149
}
159
150
}
@@ -173,34 +164,14 @@ public interface GlideSubcompositionScope {
173
164
public val painter: Painter
174
165
}
175
166
176
- @OptIn(ExperimentGlideFlows ::class )
177
167
@ExperimentalGlideComposeApi
178
168
internal class GlideSubcompositionScopeImpl (
179
- private val value : GlideFlowInstant <Drawable >? ,
169
+ private val drawable : Drawable ? ,
170
+ override val state : RequestState
180
171
) : GlideSubcompositionScope {
181
172
182
173
override val painter: Painter
183
- get() = value?.drawable()?.toPainter() ? : ColorPainter (Color .Transparent )
184
-
185
- override val state: RequestState
186
- get() = when (val current = value) {
187
- is com.bumptech.glide.integration.ktx.Placeholder -> {
188
- when (current.status) {
189
- Status .CLEARED -> RequestState .Loading
190
- Status .RUNNING -> RequestState .Loading
191
- Status .FAILED -> RequestState .Failure
192
- Status .SUCCEEDED -> throw IllegalStateException ()
193
- }
194
- }
195
-
196
- is Resource -> RequestState .Success (current.dataSource)
197
- null -> RequestState .Loading
198
- }
199
-
200
- private fun GlideFlowInstant<Drawable>.drawable (): Drawable ? = when (this ) {
201
- is com.bumptech.glide.integration.ktx.Placeholder -> placeholder
202
- is Resource -> resource
203
- }
174
+ get() = drawable?.toPainter() ? : ColorPainter (Color .Transparent )
204
175
205
176
private fun Drawable.toPainter (): Painter =
206
177
when (this ) {
@@ -210,19 +181,6 @@ internal class GlideSubcompositionScopeImpl(
210
181
}
211
182
}
212
183
213
- @OptIn(InternalGlideApi ::class )
214
- private fun Modifier.sizeObservingModifier (size : ResolvableGlideSize ): Modifier =
215
- this .layout { measurable, constraints ->
216
- if (size is AsyncGlideSize ) {
217
- val inferredSize = constraints.inferredGlideSize()
218
- if (inferredSize != null ) {
219
- size.setSize(inferredSize)
220
- }
221
- }
222
- val placeable = measurable.measure(constraints)
223
- layout(placeable.width, placeable.height) { placeable.place(0 , 0 ) }
224
- }
225
-
226
184
/* *
227
185
* The current state of a request associated with a Glide painter.
228
186
*
@@ -295,7 +253,7 @@ public sealed class RequestState {
295
253
* load never starting, or in an unreasonably large amount of memory being used. Loading overly
296
254
* large images in memory can also impact scrolling performance.
297
255
*/
298
- @OptIn(InternalGlideApi ::class , ExperimentGlideFlows :: class )
256
+ @OptIn(InternalGlideApi ::class )
299
257
@ExperimentalGlideComposeApi
300
258
@Composable
301
259
public fun GlideSubcomposition (
@@ -310,27 +268,45 @@ public fun GlideSubcomposition(
310
268
requestBuilderTransform(requestManager.load(model))
311
269
}
312
270
313
- val overrideSize = requestBuilder.overrideSize()
314
- val size = remember(overrideSize) {
315
- if (overrideSize != null ) {
316
- ImmediateGlideSize (overrideSize)
317
- } else {
318
- AsyncGlideSize ()
271
+ val requestState: MutableState <RequestState > =
272
+ remember(model, requestManager, requestBuilderTransform) {
273
+ mutableStateOf(RequestState .Loading )
319
274
}
275
+ val drawable: MutableState <Drawable ?> = remember(model, requestManager, requestBuilderTransform) {
276
+ mutableStateOf(null )
320
277
}
321
278
322
- val result = remember(requestBuilder, size) {
323
- requestBuilder.flowResolvable(size)
324
- }.collectAsState(initial = null )
279
+ val requestListener: StateTrackingListener =
280
+ remember(model, requestManager, requestBuilderTransform) {
281
+ StateTrackingListener (
282
+ requestState,
283
+ drawable
284
+ )
285
+ }
325
286
326
- val scope = GlideSubcompositionScopeImpl (result .value)
287
+ val scope = GlideSubcompositionScopeImpl (drawable.value, requestState .value)
327
288
328
- if (overrideSize != null ) {
289
+ Box (
290
+ modifier
291
+ .glideNode(
292
+ requestBuilder,
293
+ draw = false ,
294
+ requestListener = requestListener,
295
+ )
296
+ ) {
329
297
scope.content()
330
- } else {
331
- Box (modifier = modifier.sizeObservingModifier(size)) {
332
- scope.content()
333
- }
298
+ }
299
+ }
300
+
301
+ @ExperimentalGlideComposeApi
302
+ private class StateTrackingListener (
303
+ val state : MutableState <RequestState >,
304
+ val drawable : MutableState <Drawable ?>
305
+ ) : RequestListener {
306
+
307
+ override fun onStateChanged (model : Any? , drawable : Drawable ? , requestState : RequestState ) {
308
+ state.value = requestState
309
+ this .drawable.value = drawable
334
310
}
335
311
}
336
312
@@ -472,31 +448,14 @@ private fun RequestBuilder<Drawable>.contentScaleTransform(
472
448
// TODO(judds): Think about how to handle the various fills
473
449
}
474
450
475
- @OptIn( InternalGlideApi :: class , ExperimentalGlideComposeApi :: class )
451
+
476
452
@Composable
477
- private fun ModifierGlideImage (
478
- requestBuilder : RequestBuilder <Drawable >,
479
- size : ImmediateGlideSize ? ,
480
- contentDescription : String? ,
453
+ private fun SimpleLayout (
481
454
modifier : Modifier ,
482
- alignment : Alignment ,
483
- contentScale : ContentScale ,
484
- alpha : Float ,
485
- colorFilter : ColorFilter ?
486
455
) {
487
456
Layout (
488
- {},
489
457
modifier
490
- .glideNode(
491
- requestBuilder,
492
- size,
493
- contentDescription,
494
- alignment,
495
- contentScale,
496
- alpha,
497
- colorFilter,
498
- )
499
- ) { _, constraints ->
458
+ ) { _, constraints ->
500
459
layout(constraints.minWidth, constraints.minHeight) {}
501
460
}
502
461
}
0 commit comments