在 Android 开发中,可以通过与生命周期(Lifecycle)深度绑定的方式实现动画的自动控制。虽然不能直接用 lifecycleScope.launch
直接操作属性动画,但可以通过以下两种更优雅的方案实现自动管理:
方案一:LifecycleObserver + 扩展函数(推荐)
kotlin
class AutoControlAnimatorListener(
private val lifecycle: Lifecycle,
private val animator: Animator
) : DefaultLifecycleObserver {
override fun onStart(owner: LifecycleOwner) {
if (animator.isPaused) {
animator.resume()
} else {
animator.start()
}
}
override fun onStop(owner: LifecycleOwner) {
if (animator.isRunning) {
animator.pause()
}
}
override fun onDestroy(owner: LifecycleOwner) {
animator.cancel()
lifecycle.removeObserver(this)
}
}
// 扩展函数
fun Animator.autoControlWithLifecycle(lifecycle: Lifecycle) {
val listener = AutoControlAnimatorListener(lifecycle, this)
lifecycle.addObserver(listener)
}
// 使用方式
val animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1f).apply {
duration = 1000
}
animator.autoControlWithLifecycle(lifecycle) // 自动绑定当前生命周期
方案二:协程结合生命周期(针对动画逻辑控制)
kotlin
// 在 ViewModel 或 Presenter 中
fun startComplexAnimation(lifecycleScope: LifecycleCoroutineScope) {
lifecycleScope.launchWhenStarted {
// 启动动画协程
val animJob = launch {
// 复杂动画逻辑控制
while (isActive) { // 自动检测生命周期状态
updateAnimationFrame()
delay(16) // 模拟 60fps
}
}
// 自动暂停
lifecycleScope.launchWhenStopped {
animJob.cancel()
}
}
}
关键原理说明:
- 生命周期感知架构
通过LifecycleObserver
监听ON_START
/ON_STOP
事件,实现与组件生命周期的精准同步 - 协程的天然优势
lifecycleScope.launchWhenXxx
可创建与生命周期状态绑定的协程作用域,适用于需要复杂控制的动画逻辑 - 动画状态保存
对于属性动画,pause() 方法会保留当前动画进度(通过保存pauseTime
和计算currentPlayTime
)
性能优化建议:
- 使用统一动画管理器
kotlin
@ExperimentalLifecycleComposeApi
@Composable
fun AnimatedContentWithLifecycle(
targetState: Any,
lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val transition = updateTransition(targetState)
DisposableEffect(lifecycle) {
val observer = object : DefaultLifecycleObserver {
override fun onPause(owner: LifecycleOwner) {
transition.pause()
}
override fun onResume(owner: LifecycleOwner) {
transition.resume()
}
}
lifecycle.addObserver(observer)
onDispose {
lifecycle.removeObserver(observer)
}
}
// 实际动画内容
}
-
针对不同场景的优化策略
场景 处理方式 优势 短暂切换应用 暂停动画 快速恢复 配置变更 保持动画 避免闪烁 彻底退出 取消动画 释放资源
注意事项:
- 组合动画处理
当使用AnimatorSet
时,需要递归处理所有子动画的状态管理 - 转场动画的特殊性
ActivityOptions.makeSceneTransitionAnimation
需要额外处理 Window 级别的动画 - Compose 动画整合
对于 Jetpack Compose,可以直接使用:
ini
val lifecycle = LocalLifecycleOwner.current.lifecycle
val animatedAlpha by animateFloatAsState(
targetValue = if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) 1f else 0f
)
- 性能监控
建议在动画控制逻辑中加入性能监控代码:
kotlin
if (BuildConfig.DEBUG) {
animator.addUpdateListener {
val frameTime = it.currentPlayTime // 监控帧耗时
DebugLog.d("AnimationFrame", "Time: $frameTime")
}
}
通过这种深度集成的生命周期管理方式,既可以实现动画的自动控制,又能保持代码的简洁性和可维护性。