使用Compose实现带暂停/恢复功能的自定义进度动画
实现带播放/暂停功能的进度条(Jetpack Compose)
要实现支持播放/暂停的进度条,核心是利用Compose的Animatable类管理进度值,并通过协程控制动画的启动与中断。以下是简洁优雅的实现方案:
核心实现代码
import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.tween import androidx.compose.foundation.Icon import androidx.compose.foundation.IconButton import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.material.Icons import androidx.compose.material.LinearProgressIndicator import androidx.compose.material.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import kotlinx.coroutines.Job import kotlinx.coroutines.launch @Composable fun PlayPauseProgressBar() { var isPlaying by remember { mutableStateOf(false) } val progress = remember { Animatable(0f) } var animationJob by remember { mutableStateOf<Job?>(null) } val coroutineScope = rememberCoroutineScope() // 启动进度动画 fun startAnimation() { isPlaying = true animationJob?.cancel() // 取消之前的动画任务,避免并发冲突 animationJob = coroutineScope.launch { progress.animateTo( targetValue = 1f, animationSpec = tween( durationMillis = 5000, // 自定义进度完成时长 easing = LinearEasing ) ) { // 动画完成后自动重置状态 if (value == 1f) { isPlaying = false progress.snapTo(0f) } } } } // 暂停进度动画 fun pauseAnimation() { isPlaying = false animationJob?.cancel() } Column( modifier = Modifier.padding(16.dp), horizontalAlignment = Alignment.CenterHorizontally ) { // 进度条组件 LinearProgressIndicator( progress = progress.value, modifier = Modifier.fillMaxWidth(), color = MaterialTheme.colors.primary, backgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.12f) ) Spacer(modifier = Modifier.height(16.dp)) // 播放/暂停切换按钮 IconButton( onClick = { if (isPlaying) pauseAnimation() else startAnimation() } ) { Icon( imageVector = if (isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow, contentDescription = if (isPlaying) "暂停" else "播放", tint = MaterialTheme.colors.primary, modifier = Modifier.size(48.dp) ) } } }
关键实现细节
Animatable的优势:作为Compose动画系统的核心类,它天然支持动画的中断、恢复与状态保存,完美适配播放/暂停场景。- 协程任务管理:通过
Job对象跟踪动画协程,点击暂停时直接取消任务,确保进度立即停在当前位置;重启时从当前进度继续动画。 - 自动重置逻辑:进度完成后自动归零并切换到暂停状态,符合常规用户预期。
- Material Design 适配:使用主题颜色系统,保证UI风格统一且可定制。
这种实现遵循Compose声明式编程范式,代码简洁易维护,能优雅处理所有启停场景。
内容的提问来源于stack exchange,提问作者Mustafa Tatarhan
相关产品推荐
相关产品推荐

