Android Kotlin开发中Rive动画play/pause/stop方法使用及崩溃解决
Android Kotlin集成Rive进度条动画:崩溃修复与play/pause/stop正确用法
崩溃常见原因及修复方案
1. 空指针异常(最频发)
调用play()/pause()/stop()时,RiveView未完成初始化或实例为null,直接触发崩溃。
- 修复:确保在View加载完成后调用方法,比如在
onViewCreated(Fragment)、onStart(Activity)中执行,或用view.post { ... }延迟到主线程消息队列执行;调用前先判断riveView.isInitialized是否为true。
2. 动画/状态机名称不匹配
代码中传入的名称与Rive源文件中的名称不一致(区分大小写),导致找不到目标动画抛出异常。
- 修复:打开Rive编辑器,确认动画/状态机的精确名称,确保代码中的字符串完全匹配。
3. Rive资源未正确加载
.riv文件放置路径错误、资源损坏,或加载时使用了错误的资源ID,导致加载失败后续调用崩溃。
- 修复:将
.riv文件放在res/raw目录下;加载时使用正确的资源ID,添加try-catch捕获加载异常,排查资源损坏或路径问题。
4. 未绑定状态机控制器(针对状态机驱动的进度条)
进度条动画通常依赖Rive状态机实现数值绑定,直接调用RiveView的控制方法可能无效或崩溃。
- 修复:先获取并绑定
StateMachineController,再通过控制器操作动画(示例见下文)。
play()方法参数详解
Rive的play()提供多种重载,适配不同场景:
- 无参
play():播放Rive文件中的默认动画/状态机(仅当文件只有一个动画/状态机,或已设置默认项时生效)。 play(animationName: String):播放指定名称的独立动画,适用于多动画共存的Rive文件。play(stateMachineName: String):启动指定名称的状态机,进度条动画通常用这种方式(状态机可绑定数值控制进度)。play(name: String, loop: Loop):指定循环模式播放,Loop可选值:Loop.ONCE:播放一次后停止Loop.LOOP:循环播放Loop.PING_PONG:来回反向播放
play/pause/stop正确使用示例
布局配置
<app.rive.runtime.kotlin.RiveView android:id="@+id/riveProgressBar" android:layout_width="match_parent" android:layout_height="wrap_content" app:riveResource="@raw/progress_bar" app:riveAutoPlay="false"/>
Kotlin代码实现
class ProgressActivity : AppCompatActivity() { private lateinit var riveView: RiveView private var stateMachineController: StateMachineController? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_progress) riveView = findViewById(R.id.riveProgressBar) // 监听Rive资源加载完成,初始化状态机控制器 riveView.registerListener(object : RiveListener { override fun onRiveLoaded(riveFile: RiveFile) { // 替换为你Rive文件中的状态机名称 stateMachineController = StateMachineController.fromRiveFile(riveFile, "ProgressStateMachine") stateMachineController?.let { controller -> riveView.controller = controller controller.start() // 示例:设置进度值(替换为你的状态机数值参数名) controller.setNumberState("Progress", 50.0) } } override fun onStateChange(stateMachineName: String, stateName: String) { // 可选:监听状态机状态变化 } }) } // 播放动画 fun playProgressAnimation() { if (riveView.isInitialized) { // 方式1:通过RiveView直接播放状态机 riveView.play("ProgressStateMachine") // 方式2:通过控制器启动(更灵活) stateMachineController?.start() } } // 暂停动画 fun pauseProgressAnimation() { if (riveView.isInitialized && riveView.isPlaying) { riveView.pause() // 或通过控制器暂停 stateMachineController?.pause() } } // 停止动画 fun stopProgressAnimation() { if (riveView.isInitialized) { riveView.stop() // 重置状态机到初始状态 stateMachineController?.reset() } } override fun onDestroy() { super.onDestroy() // 释放控制器资源,避免内存泄漏 stateMachineController?.dispose() } }
关键注意事项
- 调用控制方法前必须检查
riveView.isInitialized,避免未初始化导致的崩溃。 - 状态机驱动的进度条,优先使用
StateMachineController控制,便于绑定进度数值、监听状态变化。 - 页面销毁时务必调用
controller.dispose()释放资源,防止内存泄漏。
内容的提问来源于stack exchange,提问作者Jayesh Hadke
相关产品推荐
相关产品推荐

