如何在Flutter中实现下载进度实时展示功能
圆形下载进度按钮实现方案
原生自定义实现(无第三方依赖)
核心思路是自定义可交互的View组件,自行处理绘制和状态切换逻辑:
- 基础绘制:分三层绘制元素,底层是灰色背景圆环,上层是随进度变化的彩色扫描圆环,中间区域根据状态显示下载图标、进度百分比、完成图标
- 进度同步:下载任务启动后,通过下载回调实时获取已下载/总大小计算得到百分比,将百分比转换为圆环扫描角度(0360度对应进度0100%),调用重绘方法更新UI即可
- 状态切换:支持未下载、下载中、下载完成、下载失败4种状态切换,点击按钮时触发对应状态的流转
核心绘制代码示例(Android Kotlin):
override fun onDraw(canvas: Canvas) { super.onDraw(canvas) // 绘制背景圆环 canvas.drawCircle(centerX, centerY, ringRadius, bgRingPaint) // 绘制进度圆环 val sweepAngle = currentProgress * 3.6f // 1%对应3.6度 canvas.drawArc(ringRect, -90f, sweepAngle, false, progressRingPaint) // 绘制中间内容 when (currentState) { STATE_PENDING -> canvas.drawBitmap(downloadIcon, null, iconRect, paint) STATE_DOWNLOADING -> canvas.drawText("${currentProgress.toInt()}%", centerX, centerY + textOffset, textPaint) STATE_FINISHED -> canvas.drawBitmap(completeIcon, null, iconRect, paint) STATE_FAILED -> canvas.drawBitmap(retryIcon, null, iconRect, paint) } }
可用第三方包
根据你使用的开发平台可以直接选成熟的封装组件,不需要自行处理绘制逻辑:
- Android平台:
CircleProgressView、DownloadProgressButton,支持自定义圆环颜色、宽度、动画插值器,适配不同按钮尺寸 - iOS平台:
MBCircularProgressBar、DACircularProgress,支持弧度自定义、进度动画、状态切换回调 - 前端/小程序平台:可以直接用组件库内置的圆形进度条组件,比如Vant的
Circle组件、Ant Design的Progress圆形模式,绑定进度变量即可自动更新
注意事项
- 进度更新操作必须在UI线程执行,避免出现线程异常
- 大文件下载时不要每收到一点数据就更新UI,建议间隔100ms或者进度每变化1%再触发重绘,减少性能消耗
- 可以添加进度过渡动画,避免进度跳变过于生硬
内容的提问来源于stack exchange,提问作者dipgirl
相关产品推荐
相关产品推荐

