You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Jetpack Compose中显示动图GIF?

如何在Jetpack Compose中显示动图GIF?

我太懂你这种无奈了!用painterResource加载GIF只显示第一帧确实挺扫兴的——毕竟它本来就是为静态图片设计的,完全没考虑动图的动画逻辑。别担心,下面给你两个实用的解决办法,选一个适合你的就行:


方法一:用Coil库(最省心的方案)

Coil是专门为Android设计的轻量级图像加载库,对Jetpack Compose支持很好,而且能自动处理GIF的动画播放,不需要你自己写复杂的帧逻辑。

步骤1:添加Coil的Compose依赖

打开你模块级别的build.gradle.kts(或者build.gradle),在dependencies里加上这行:

implementation("io.coil-kt:coil-compose:2.5.0")

(版本号可以根据你项目的需求换成最新稳定版)

步骤2:用Coil的Painter加载GIF

把原来的painterResource换成Coil提供的rememberAsyncImagePainter,代码就像这样:

Image(
    painter = rememberAsyncImagePainter(R.drawable.your_gif),
    contentDescription = "你的动图描述",
    modifier = Modifier.size(150.dp),
    contentScale = ContentScale.Crop
)

这样一来,GIF就能正常动起来了,Coil会帮你搞定所有的帧播放、内存管理这些细节。


方法二:自定义Painter(不用第三方库)

如果你不想给项目加额外的依赖,也可以自己写一个简单的Painter来解析和播放GIF。不过这个方法对复杂GIF的支持可能有限,比如不同帧时长、透明帧的情况,需要你自己测试调整。

步骤1:创建自定义的GIF Painter

写一个@Composable函数来创建并缓存这个Painter:

@Composable
fun rememberGifPainter(gifResId: Int): Painter {
    val context = LocalContext.current
    val painter = remember {
        object : Painter() {
            // 解析GIF资源
            private val movie = Movie.decodeStream(context.resources.openRawResource(gifResId))
            // 记录当前播放到的时间
            private var currentTime by mutableStateOf(0L)
            // 计算每帧的时长(简单处理,假设所有帧时长相同)
            private val frameDuration = movie.duration() / movie.frameCount()

            // 返回GIF的原始尺寸
            override val intrinsicSize: Size
                get() = Size(movie.width().toFloat(), movie.height().toFloat())

            // 绘制每一帧
            override fun DrawScope.onDraw() {
                // 设置当前要绘制的帧
                movie.setTime((currentTime % movie.duration()).toInt())
                // 把帧画到Canvas上
                movie.draw(this.canvas.nativeCanvas, 0f, 0f, size.width, size.height)
                // 下一帧更新时间并触发重绘
                withFrameNanos {
                    currentTime += frameDuration
                    this@object.invalidate()
                }
            }
        }
    }
    return painter
}

步骤2:使用自定义Painter

和之前一样,在Image composable里用这个自定义的painter:

Image(
    painter = rememberGifPainter(R.drawable.your_gif),
    contentDescription = "你的动图描述",
    modifier = Modifier.size(150.dp),
    contentScale = ContentScale.Crop
)

总结

如果项目里还没有图像加载库,优先选Coil的方案,省心又稳定;如果对依赖体积有要求,再试试自定义Painter的方法,记得多测试几种不同的GIF哦。

内容来源于stack exchange

火山引擎 最新活动