From e46d8d39f9fddade6c16ebae49ede4d5c0e1afb7 Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Fri, 8 Apr 2022 16:53:38 +0100 Subject: [PATCH 1/6] Fix DrawablePainter not reacting to intrinsic size changes Currently DrawablePainter has an `invalidateTick` which triggers a draw pass, but there is nothing to trigger a layout pass. This PR adds another tick for layout, which is triggered when the intrinsic size changes. --- .../drawablepainter/DrawablePainter.kt | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt index 96956cb0d..1b578e12f 100644 --- a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt +++ b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt @@ -59,12 +59,20 @@ class DrawablePainter( val drawable: Drawable ) : Painter(), RememberObserver { private var invalidateTick by mutableStateOf(0) + private var layoutTick by mutableStateOf(0) + + private var lastIntrinsicSize: Size = Size.Unspecified private val callback: Drawable.Callback by lazy { object : Drawable.Callback { override fun invalidateDrawable(d: Drawable) { // Update the tick so that we get re-drawn invalidateTick++ + + if (lastIntrinsicSize != drawable.intrinsicSize) { + // If the intrinsic size has changed, update the layout tick + layoutTick++ + } } override fun scheduleDrawable(d: Drawable, what: Runnable, time: Long) { @@ -121,15 +129,10 @@ class DrawablePainter( } override val intrinsicSize: Size - get() = when { - // Only return a finite size if the drawable has an intrinsic size - drawable.intrinsicWidth >= 0 && drawable.intrinsicHeight >= 0 -> { - Size( - width = drawable.intrinsicWidth.toFloat(), - height = drawable.intrinsicHeight.toFloat(), - ) - } - else -> Size.Unspecified + get() { + // Reading this ensures that we re-layout when invalidateDrawable() is called + layoutTick + return drawable.intrinsicSize.also { lastIntrinsicSize = it } } override fun DrawScope.onDraw() { @@ -170,6 +173,15 @@ fun rememberDrawablePainter(drawable: Drawable?): Painter = remember(drawable) { } } +private val Drawable.intrinsicSize: Size + get() = when { + // Only return a finite size if the drawable has an intrinsic size + intrinsicWidth >= 0 && intrinsicHeight >= 0 -> { + Size(width = intrinsicWidth.toFloat(), height = intrinsicHeight.toFloat()) + } + else -> Size.Unspecified + } + internal object EmptyPainter : Painter() { override val intrinsicSize: Size get() = Size.Unspecified override fun DrawScope.onDraw() {} From 66e604324f1b197bdfb3ba90e1bbb14e57ef681c Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Tue, 12 Apr 2022 08:35:51 +0100 Subject: [PATCH 2/6] Rename tick properties --- .../accompanist/drawablepainter/DrawablePainter.kt | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt index 1b578e12f..79aac426f 100644 --- a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt +++ b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt @@ -58,8 +58,8 @@ private val MAIN_HANDLER by lazy(LazyThreadSafetyMode.NONE) { class DrawablePainter( val drawable: Drawable ) : Painter(), RememberObserver { - private var invalidateTick by mutableStateOf(0) - private var layoutTick by mutableStateOf(0) + private var drawInvalidateTick by mutableStateOf(0) + private var sizeInvalidateTick by mutableStateOf(0) private var lastIntrinsicSize: Size = Size.Unspecified @@ -67,7 +67,7 @@ class DrawablePainter( object : Drawable.Callback { override fun invalidateDrawable(d: Drawable) { // Update the tick so that we get re-drawn - invalidateTick++ + drawInvalidateTick++ if (lastIntrinsicSize != drawable.intrinsicSize) { // If the intrinsic size has changed, update the layout tick @@ -130,15 +130,16 @@ class DrawablePainter( override val intrinsicSize: Size get() { - // Reading this ensures that we re-layout when invalidateDrawable() is called - layoutTick + // Reading this ensures that we re-layout when the instrinsic size changes + sizeInvalidateTick + return drawable.intrinsicSize.also { lastIntrinsicSize = it } } override fun DrawScope.onDraw() { drawIntoCanvas { canvas -> // Reading this ensures that we invalidate when invalidateDrawable() is called - invalidateTick + drawInvalidateTick // Update the Drawable's bounds drawable.setBounds(0, 0, size.width.roundToInt(), size.height.roundToInt()) From f681dac37a55679900369feaf0664ddc03d0e610 Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Tue, 12 Apr 2022 08:38:34 +0100 Subject: [PATCH 3/6] Fix spotless --- .../com/google/accompanist/drawablepainter/DrawablePainter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt index 79aac426f..c2b3aa070 100644 --- a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt +++ b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt @@ -132,7 +132,7 @@ class DrawablePainter( get() { // Reading this ensures that we re-layout when the instrinsic size changes sizeInvalidateTick - + return drawable.intrinsicSize.also { lastIntrinsicSize = it } } From 72942a1d7cdbb1411a9ed6c59ec85177e201d051 Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Tue, 12 Apr 2022 08:40:20 +0100 Subject: [PATCH 4/6] Fix property rename That will teach me for trying to do this via the web editor --- .../com/google/accompanist/drawablepainter/DrawablePainter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt index c2b3aa070..6ee1a0c2b 100644 --- a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt +++ b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt @@ -71,7 +71,7 @@ class DrawablePainter( if (lastIntrinsicSize != drawable.intrinsicSize) { // If the intrinsic size has changed, update the layout tick - layoutTick++ + sizeInvalidateTick++ } } From 6d7332da1eab605f0057e247aa9abf00aa452c72 Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Tue, 28 Jun 2022 16:02:34 +0100 Subject: [PATCH 5/6] Move away from using a tick for size changes We now just rely on the Drawable notifying the painter from invalidateDrawable() --- .../drawablepainter/DrawablePainter.kt | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt index 6ee1a0c2b..59e9918b3 100644 --- a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt +++ b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt @@ -59,20 +59,15 @@ class DrawablePainter( val drawable: Drawable ) : Painter(), RememberObserver { private var drawInvalidateTick by mutableStateOf(0) - private var sizeInvalidateTick by mutableStateOf(0) - - private var lastIntrinsicSize: Size = Size.Unspecified + private var drawableIntrinsicSize by mutableStateOf(Size.Unspecified) private val callback: Drawable.Callback by lazy { object : Drawable.Callback { override fun invalidateDrawable(d: Drawable) { // Update the tick so that we get re-drawn drawInvalidateTick++ - - if (lastIntrinsicSize != drawable.intrinsicSize) { - // If the intrinsic size has changed, update the layout tick - sizeInvalidateTick++ - } + // Update our intrinsic size too + drawableIntrinsicSize = drawable.intrinsicSize } override fun scheduleDrawable(d: Drawable, what: Runnable, time: Long) { @@ -128,13 +123,7 @@ class DrawablePainter( return false } - override val intrinsicSize: Size - get() { - // Reading this ensures that we re-layout when the instrinsic size changes - sizeInvalidateTick - - return drawable.intrinsicSize.also { lastIntrinsicSize = it } - } + override val intrinsicSize: Size get() = drawableIntrinsicSize override fun DrawScope.onDraw() { drawIntoCanvas { canvas -> From a2fde107a1406672809ca2531ed102efc4b5c118 Mon Sep 17 00:00:00 2001 From: Chris Banes Date: Tue, 28 Jun 2022 16:40:27 +0100 Subject: [PATCH 6/6] Init using the drawable instrinsic size --- .../com/google/accompanist/drawablepainter/DrawablePainter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt index 59e9918b3..319b9a6b3 100644 --- a/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt +++ b/drawablepainter/src/main/java/com/google/accompanist/drawablepainter/DrawablePainter.kt @@ -59,7 +59,7 @@ class DrawablePainter( val drawable: Drawable ) : Painter(), RememberObserver { private var drawInvalidateTick by mutableStateOf(0) - private var drawableIntrinsicSize by mutableStateOf(Size.Unspecified) + private var drawableIntrinsicSize by mutableStateOf(drawable.intrinsicSize) private val callback: Drawable.Callback by lazy { object : Drawable.Callback {