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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:10:16