theme: cyanosis
持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 1 天,点击查看活动详情
在上传文件时,为了缓解等待的焦虑,一般希望显示上传的 进度
,来给用户任务进度的 反馈
。在上传图片时,经常见到给出一个透明遮罩,随着进度的增加,遮罩逐渐减少的进度表现形式。本文就来看一下这种表现的实现方式:
整体分为三层,底部的图片层、中间的透明遮罩层、上面的文字层。其中透明遮罩会根据进度,以中心为原点,顺时针扫描式地减少。这个效果可以通过 裁剪
完成,如下 35%
时,相当于把右上角裁掉,保留余下的阴影。所以关键点是: 计算余下阴影的路径
。
如下示意图,根据红色是图片矩形区域的路径;蓝色实线是外接圆上的弧线,弧度值根据进度确定。根据这两个路径进行 xor
的组合,就可以得到阴影路径:
如下,定义 CustomClipper<Path>
的派生类 ProgressClipper
, 在构造时传入进度值。实现 getClip
抽象方法返回 Path
路径对象。裁剪器会根据这个路径进行裁剪,该路径之外的部分会被裁掉。shouldReclip
方法和绘制中的的 shouldRepaint
异曲同工,在 ProgressClipper
对象变化时,控制是否触发 getClip
重新裁剪。
使用 ClipPath
组件,设置 clipper
参数,其类型为 CustomClipper<Path>
,可对 child
组件进行裁剪,如下是使用 ProgressClipper
裁剪器,进度 0.35
时的效果:
然后通过 Stack
组件,将 Image
放在遮罩的下层,文字放在上层,效果如下:
然后只要更改进度值,即可完成需求,这里通过 Timer
定时器来模拟进度的变化,每 500 ms
增加 0.05
进度。代码如下所示:
另外,通过 ValueListenableBuilder
来监听 uploadProgress
进度变化。计时器每次触发回调时,增加 uploadProgress.value
值即可触发局部构建。这样即可得到如下效果:
在实际上传时,可以使用 Dio
的 post
请求,通过 onSendProgress
可以监听到上传的进度,在其中更新进度值即可。
裁剪的表现本质上是路径,所以通过提供不同的路径可以实现不同的效果。如下是随进度增加,阴影区域圆形缩减的效果:
该效果通过下面的 CircleProgressClipper
裁剪器实现。逻辑非常简单,进度不断增大,半径逐渐减小,通过 outSide
乘以 1-progress
即可:
还可以让遮罩以矩形的方式逐渐缩减,如下图所示:
在创建矩形区域时,左下角的纵坐标值取 size.height*(1-progress)
即可。另外,阴影从 左到右
、右到左
、上到下
的变化都是类似的,有相关需求的话自己改改即可,当然也可以通过一个枚举类作为参数来控制表现效果。
本文主要通过图片上传的进度表现,介绍了 CustomClipper
裁剪器的派生和使用,希望可以为你的图片上传有所帮助。那本文就到这,谢谢观看 ~
@张风捷特烈 2022.09.30 未允禁转