Skip to content

Commit 59c2d9b

Browse files
committedSep 3, 2023
Fix drawables not animating via a custom DrawablePainter
1 parent 374306f commit 59c2d9b

File tree

4 files changed

+101
-3
lines changed

4 files changed

+101
-3
lines changed
 

‎integration/compose/build.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ dependencies {
5353
}
5454
implementation libs.compose.foundation
5555
implementation libs.compose.ui
56-
implementation libs.drawablepainter
5756
implementation libs.androidx.core.ktx
5857
debugImplementation libs.compose.ui.testmanifest
5958
androidTestImplementation libs.junit

‎integration/compose/src/main/java/com/bumptech/glide/integration/compose/GlideModifier.kt

+32
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package com.bumptech.glide.integration.compose
22

33
import android.graphics.PointF
4+
import android.graphics.drawable.Animatable
45
import android.graphics.drawable.Drawable
6+
import android.os.Handler
7+
import android.os.Looper
58
import androidx.compose.ui.Alignment
69
import androidx.compose.ui.ExperimentalComposeUiApi
710
import androidx.compose.ui.Modifier
@@ -146,6 +149,10 @@ internal data class GlideNodeElement constructor(
146149
}
147150
}
148151

152+
private val MAIN_HANDLER by lazy(LazyThreadSafetyMode.NONE) {
153+
Handler(Looper.getMainLooper())
154+
}
155+
149156
@ExperimentalGlideComposeApi
150157
@OptIn(InternalGlideApi::class)
151158
internal class GlideNode : DrawModifierNode, LayoutModifierNode, SemanticsModifierNode,
@@ -178,6 +185,23 @@ internal class GlideNode : DrawModifierNode, LayoutModifierNode, SemanticsModifi
178185

179186
private var transition: Transition = DoNotTransition
180187

188+
189+
private val callback: Drawable.Callback by lazy {
190+
object : Drawable.Callback {
191+
override fun invalidateDrawable(d: Drawable) {
192+
invalidateDraw()
193+
}
194+
195+
override fun scheduleDrawable(d: Drawable, what: Runnable, time: Long) {
196+
MAIN_HANDLER.postAtTime(what, time)
197+
}
198+
199+
override fun unscheduleDrawable(d: Drawable, what: Runnable) {
200+
MAIN_HANDLER.removeCallbacks(what)
201+
}
202+
}
203+
}
204+
181205
private fun RequestBuilder<*>.maybeImmediateSize() =
182206
this.overrideSize()?.let { ImmediateGlideSize(it) }
183207

@@ -398,7 +422,15 @@ internal class GlideNode : DrawModifierNode, LayoutModifierNode, SemanticsModifi
398422

399423
private fun updateDrawable(drawable: Drawable?) {
400424
this.drawable = drawable
425+
426+
this.drawable?.callback = null
427+
this.drawable?.setVisible(false, false)
428+
(this.drawable as? Animatable)?.stop()
429+
401430
painter = drawable?.toPainter()
431+
drawable?.callback = callback
432+
drawable?.setVisible(true, true)
433+
(drawable as? Animatable)?.start()
402434
drawablePositionAndSize = null
403435
}
404436

‎integration/compose/src/main/java/com/bumptech/glide/integration/compose/Painter.kt

+69-1
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ package com.bumptech.glide.integration.compose
33
import android.graphics.drawable.BitmapDrawable
44
import android.graphics.drawable.ColorDrawable
55
import android.graphics.drawable.Drawable
6+
import android.os.Build
7+
import android.view.View
8+
import androidx.compose.ui.geometry.Size
69
import androidx.compose.ui.graphics.Color
10+
import androidx.compose.ui.graphics.ColorFilter
11+
import androidx.compose.ui.graphics.asAndroidColorFilter
712
import androidx.compose.ui.graphics.asImageBitmap
13+
import androidx.compose.ui.graphics.drawscope.DrawScope
14+
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
15+
import androidx.compose.ui.graphics.nativeCanvas
816
import androidx.compose.ui.graphics.painter.BitmapPainter
917
import androidx.compose.ui.graphics.painter.ColorPainter
1018
import androidx.compose.ui.graphics.painter.Painter
11-
import com.google.accompanist.drawablepainter.DrawablePainter
19+
import androidx.compose.ui.graphics.withSave
20+
import androidx.compose.ui.unit.IntSize
21+
import androidx.compose.ui.unit.LayoutDirection
22+
import androidx.compose.ui.unit.toSize
23+
import kotlin.math.roundToInt
1224

1325
internal fun Drawable?.toPainter(): Painter =
1426
when (this) {
@@ -17,3 +29,59 @@ internal fun Drawable?.toPainter(): Painter =
1729
null -> ColorPainter(Color.Transparent)
1830
else -> DrawablePainter(mutate())
1931
}
32+
33+
private class DrawablePainter(
34+
val drawable: Drawable
35+
) : Painter() {
36+
init {
37+
if (drawable.isIntrinsicSizeValid) {
38+
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
39+
}
40+
}
41+
42+
private var drawableIntrinsicSize = drawable.intrinsicSize
43+
44+
private val Drawable.isIntrinsicSizeValid
45+
get() = intrinsicWidth >= 0 && intrinsicHeight >= 0
46+
47+
private val Drawable.intrinsicSize: Size
48+
get() = if (isIntrinsicSizeValid) {
49+
IntSize(intrinsicWidth, intrinsicHeight).toSize()
50+
} else {
51+
Size.Unspecified
52+
}
53+
54+
override fun applyAlpha(alpha: Float): Boolean {
55+
drawable.alpha = (alpha * 255).roundToInt().coerceIn(0, 255)
56+
return true
57+
}
58+
59+
override fun applyColorFilter(colorFilter: ColorFilter?): Boolean {
60+
drawable.colorFilter = colorFilter?.asAndroidColorFilter()
61+
return true
62+
}
63+
64+
override fun applyLayoutDirection(layoutDirection: LayoutDirection): Boolean {
65+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
66+
return drawable.setLayoutDirection(
67+
when (layoutDirection) {
68+
LayoutDirection.Ltr -> View.LAYOUT_DIRECTION_LTR
69+
LayoutDirection.Rtl -> View.LAYOUT_DIRECTION_RTL
70+
}
71+
)
72+
}
73+
return false
74+
}
75+
76+
override val intrinsicSize: Size get() = drawableIntrinsicSize
77+
78+
override fun DrawScope.onDraw() {
79+
drawIntoCanvas { canvas ->
80+
drawable.setBounds(0, 0, size.width.roundToInt(), size.height.roundToInt())
81+
82+
canvas.withSave {
83+
drawable.draw(canvas.nativeCanvas)
84+
}
85+
}
86+
}
87+
}

‎settings.gradle

-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ dependencyResolutionManagement {
115115
library('dagger-android.support', 'com.google.dagger', 'dagger-android-support').versionRef('dagger')
116116
library('dagger-android.processor', 'com.google.dagger', 'dagger-android-processor').versionRef('dagger')
117117
library('dokka-gradle', 'org.jetbrains.dokka:dokka-gradle-plugin:1.7.10')
118-
library('drawablepainter', 'com.google.accompanist:accompanist-drawablepainter:0.25.1')
119118
library('errorprone-annotations', 'com.google.errorprone', 'error_prone_annotations').versionRef('errorprone')
120119
library('errorprone-core', 'com.google.errorprone', 'error_prone_core').versionRef('errorprone')
121120
library('errorprone-gradle', 'net.ltgt.gradle:gradle-errorprone-plugin:2.0.2')

0 commit comments

Comments
 (0)
Please sign in to comment.