Last active
January 9, 2024 20:43
-
-
Save madushans/5a251bdf6d07745495f316a4f232c36e to your computer and use it in GitHub Desktop.
Load images with blurred thumbnail load effect using Jetpack Compose, Glide and StateFlow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Adapted from https://gist.github.com/lelandrichardson/de674fe6788d922fc84362fdae530464 | |
@Composable | |
fun ExampleUsage(){ | |
GlideImage(src = "source-path", | |
blurThumbSrc = "fast-to-load-small-thumbnail-path-for-blur effect" | |
){imageBitmap -> | |
if (imageBitmap != null) { | |
Image(bitmap = imageBitmap, | |
// modifier = ... | |
) | |
} | |
else { | |
// handle fallback | |
// i.e. net disconnected or both urls failed .etc. | |
} | |
} | |
} | |
fun GlideImage(src: String, | |
blurThumbSrc: String? = null, | |
content: @Composable (ImageBitmap?) -> Unit) { | |
val view = AmbientView.current | |
val density = AmbientDensity.current | |
WithConstraints { | |
val width = with(density) { maxWidth.toIntPx() } | |
val height = with(density) { maxHeight.toIntPx() } | |
val flow = remember(src, blurThumbSrc) { | |
loadImage( | |
view, | |
width, | |
height, | |
src, | |
blurThumbSrc) | |
}.collectAsState() | |
content(flow.value?.asImageBitmap()) | |
} | |
} | |
private fun loadImage(view: View, | |
width:Int, | |
height:Int, | |
src: String, | |
blurThumbnailSrc: String?): StateFlow<Bitmap?> { | |
val resultFlow = MutableStateFlow<Bitmap?>(null) | |
val listener = GlideRequestListener(resultFlow) | |
var glide = Glide | |
.with(view) | |
.asBitmap() | |
if (blurThumbnailSrc != null) { | |
val thumbnailBuilder = Glide | |
.with(view.context) | |
.asBitmap() | |
.load(blurThumbnailSrc) | |
.override(width, height) // scale up so the soft blur looks nicer. | |
.addListener(listener) | |
.transform(BlurTransformation(70, 3)) | |
glide = glide.thumbnail(thumbnailBuilder) | |
} | |
glide | |
.load(src) | |
.addListener(listener) | |
.preload() | |
return resultFlow | |
} | |
private class GlideRequestListener(val resultFlow: MutableStateFlow<Bitmap?>):RequestListener<Bitmap> { | |
override fun onLoadFailed( | |
e: GlideException?, | |
model: Any?, | |
target: Target<Bitmap>?, | |
isFirstResource: Boolean | |
): Boolean { | |
e!!.printStackTrace() | |
return false | |
} | |
override fun onResourceReady( | |
resource: Bitmap?, | |
_model: Any?, | |
target: Target<Bitmap>?, | |
dataSource: DataSource?, | |
isFirstResource: Boolean | |
): Boolean { | |
resultFlow.value = resource | |
return true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment