You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android中Jetpack Compose集成Rive动画的自定义实现方案

在Jetpack Compose中自定义实现Rive动画组件

刚接触Rive的开发者请注意,目前Rive官方尚未提供适配Jetpack Compose的Composable组件支持,以下是经过验证的自定义实现方案,已在企业项目中稳定运行。

/**
 * RiveAnimation 是一个自定义Composable,用于在Compose中展示原生的RiveAnimationView(XML组件)。
 * 截至2023年12月6日,Rive官方尚未完成适配XML组件的Composable,因此编写了这个实现。
 *
 * Rive官方仍在修复Jetpack Compose预览功能的相关问题,在此之前,我们通过[LocalInspectionMode]
 * 在预览模式下用Rive的logo图片替代真实动画,避免预览崩溃。
 * 
 * 作者:LeviD 2023年12月
 */
@Composable
fun RiveAnimation(
    modifier: Modifier = Modifier,
    @RawRes resId: Int,
    autoplay: Boolean = true,
    artboardName: String? = null,
    animationName: String? = null,
    stateMachineName: String? = null,
    fit: Fit = Fit.CONTAIN,
    alignment: Alignment = Alignment.CENTER,
    loop: Loop = Loop.AUTO,
    contentDescription: String?,
    updateFunction: (RiveAnimationView) -> Unit = { _ -> }
) {
    if (LocalInspectionMode.current) { // 仅开发预览时生效,详见上方注释
        Image(
            modifier = modifier.size(100.dp),
            painter = painterResource(id = R.drawable.rive_logo), // 可替换为你自己的图片(.png格式)
            contentDescription = contentDescription
        )
    } else {
        val semantics = if (contentDescription != null) {
            Modifier.semantics {
                this.contentDescription = contentDescription
                this.role = Role.Image
            }
        } else {
            Modifier
        }

        AndroidView(
            modifier = modifier
                .then(semantics)
                .clipToBounds(),
            factory = { context ->
                RiveAnimationView(context).apply {
                    setRiveResource(
                        resId,
                        artboardName,
                        animationName,
                        stateMachineName,
                        autoplay,
                        fit,
                        alignment,
                        loop
                    )
                }
            },
            update = { updateFunction.invoke(it) }
        )
    }
}

使用方法

以下是带动画状态监听的使用示例:

RiveAnimation(
    resId = R.raw.animation_file, // 你的Rive动画文件,放在raw目录下
    autoplay = true,
    animationName = "Timeline 1",
    contentDescription = "动画描述"
) {
    val listener = object : RiveFileController.Listener {
        override fun notifyLoop(animation: PlayableInstance) {
            // 监听动画循环事件
        }

        override fun notifyPause(animation: PlayableInstance) {
            // 监听动画暂停事件
        }

        override fun notifyPlay(animation: PlayableInstance) {
            // 监听动画播放事件
        }

        override fun notifyStateChanged(
            stateMachineName: String,
            stateName: String
        ) {
            // 监听状态机状态变更事件
        }

        override fun notifyStop(animation: PlayableInstance) {
            enableButton = true // enableButton是Composable中的可变状态变量,动画停止时启用下一步按钮
        }
    }
    it.registerListener(listener)
}

该示例会监听名为"Timeline 1"的动画结束事件,当动画停止时将enableButton设为true,从而启用界面上的“下一步”按钮。

我尝试过多种在Compose中集成Rive且不破坏预览功能的方案,此方案在企业项目中表现最优,如有疑问可随时交流。

内容的提问来源于stack exchange,提问作者levCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:33:21