Skip to content

Commit

Permalink
Add a Transition API and a CrossFade Transition for Compose
Browse files Browse the repository at this point in the history
Similar to Glide's existing Transitions, but intended for use with
Animatable instead of views. I've started with a simple CrossFade.
  • Loading branch information
sjudd committed Aug 17, 2023
1 parent cb2b1dc commit 8e21897
Show file tree
Hide file tree
Showing 6 changed files with 354 additions and 55 deletions.
26 changes: 25 additions & 1 deletion integration/compose/api/compose.api
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
public final class com/bumptech/glide/integration/compose/CrossFade : com/bumptech/glide/integration/compose/Transition$Factory {
public static final field $stable I
public static final field Companion Lcom/bumptech/glide/integration/compose/CrossFade$Companion;
public fun <init> (Landroidx/compose/animation/core/AnimationSpec;)V
public fun build ()Lcom/bumptech/glide/integration/compose/Transition;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
}

public final class com/bumptech/glide/integration/compose/CrossFade$Companion : com/bumptech/glide/integration/compose/Transition$Factory {
public fun build ()Lcom/bumptech/glide/integration/compose/Transition;
}

public abstract interface annotation class com/bumptech/glide/integration/compose/ExperimentalGlideComposeApi : java/lang/annotation/Annotation {
}

public final class com/bumptech/glide/integration/compose/GlideImageKt {
public static final fun GlideImage (Ljava/lang/Object;Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;Lcom/bumptech/glide/integration/compose/Placeholder;Lcom/bumptech/glide/integration/compose/Placeholder;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;II)V
public static final fun GlideImage (Ljava/lang/Object;Ljava/lang/String;Landroidx/compose/ui/Modifier;Landroidx/compose/ui/Alignment;Landroidx/compose/ui/layout/ContentScale;FLandroidx/compose/ui/graphics/ColorFilter;Lcom/bumptech/glide/integration/compose/Placeholder;Lcom/bumptech/glide/integration/compose/Placeholder;Lcom/bumptech/glide/integration/compose/Transition$Factory;Lkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;III)V
public static final fun GlideSubcomposition (Ljava/lang/Object;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V
public static final fun placeholder (I)Lcom/bumptech/glide/integration/compose/Placeholder;
public static final fun placeholder (Landroid/graphics/drawable/Drawable;)Lcom/bumptech/glide/integration/compose/Placeholder;
Expand Down Expand Up @@ -54,3 +67,14 @@ public final class com/bumptech/glide/integration/compose/RequestState$Success :
public fun toString ()Ljava/lang/String;
}

public abstract interface class com/bumptech/glide/integration/compose/Transition {
public abstract fun getDrawCurrent ()Lkotlin/jvm/functions/Function5;
public abstract fun getDrawPlaceholder ()Lkotlin/jvm/functions/Function5;
public abstract fun stop (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun transition (Lkotlin/jvm/functions/Function0;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}

public abstract interface class com/bumptech/glide/integration/compose/Transition$Factory {
public abstract fun build ()Lcom/bumptech/glide/integration/compose/Transition;
}

Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.bumptech.glide.integration.compose

import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
Expand All @@ -15,8 +13,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
Expand All @@ -26,10 +22,7 @@ import androidx.compose.ui.platform.LocalInspectionMode
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.RequestManager
import com.bumptech.glide.integration.ktx.InternalGlideApi
import com.bumptech.glide.load.DataSource
import com.google.accompanist.drawablepainter.DrawablePainter
import com.google.accompanist.drawablepainter.rememberDrawablePainter

/** Mutates and returns the given [RequestBuilder] to apply relevant options. */
public typealias RequestBuilderTransform<T> = (RequestBuilder<T>) -> RequestBuilder<T>
Expand Down Expand Up @@ -77,6 +70,13 @@ public typealias RequestBuilderTransform<T> = (RequestBuilder<T>) -> RequestBuil
* opposed to resource id or [Drawable]), this [Placeholder] will not be used unless the `error`
* [RequestBuilder] also fails. This parameter does not override error [RequestBuilder]s, only error
* resource ids and/or [Drawable]s.
* @param transition An optional [Transition.Factory] that can animate the transition from a
* placeholder to a loaded image. The transition will only be called once, when the load transitions
* from showing the placeholder to showing the first resource. The transition will persist across
* multiple resources if you're using thumbnail, but will not be called for each successive resource
* in the request chain. The transition factory will not be called across different requests if
* multiple are made. The transition will not be called if you use [placeholder] or [failure] with
* the deprecated [Composable] API. See [CrossFade]
*/
// TODO(judds): the API here is not particularly composeesque, we should consider alternatives
// to RequestBuilder (though thumbnail() may make that a challenge).
Expand All @@ -95,6 +95,7 @@ public fun GlideImage(
// See http://shortn/_x79pjkMZIH for an internal discussion.
loading: Placeholder? = null,
failure: Placeholder? = null,
transition: Transition.Factory? = null,
// TODO(judds): Consider defaulting to load the model here instead of always doing so below.
requestBuilderTransform: RequestBuilderTransform<Drawable> = { it },
) {
Expand Down Expand Up @@ -144,6 +145,7 @@ public fun GlideImage(
contentScale,
alpha,
colorFilter,
transition,
)
)
}
Expand Down Expand Up @@ -173,12 +175,6 @@ internal class GlideSubcompositionScopeImpl(
override val painter: Painter
get() = drawable?.toPainter() ?: ColorPainter(Color.Transparent)

private fun Drawable.toPainter(): Painter =
when (this) {
is BitmapDrawable -> BitmapPainter(bitmap.asImageBitmap())
is ColorDrawable -> ColorPainter(Color(color))
else -> DrawablePainter(mutate())
}
}

/**
Expand Down Expand Up @@ -253,7 +249,6 @@ public sealed class RequestState {
* load never starting, or in an unreasonably large amount of memory being used. Loading overly
* large images in memory can also impact scrolling performance.
*/
@OptIn(InternalGlideApi::class)
@ExperimentalGlideComposeApi
@Composable
public fun GlideSubcomposition(
Expand Down Expand Up @@ -325,7 +320,7 @@ private fun PreviewResourceOrDrawable(
throw IllegalArgumentException("Composables should go through the production codepath")
}
Image(
painter = rememberDrawablePainter(drawable),
painter = remember(drawable) { drawable.toPainter() },
modifier = modifier,
contentDescription = contentDescription,
)
Expand Down
Loading

0 comments on commit 8e21897

Please sign in to comment.