仿支付宝完成动画
ZFinishImage.gif ZFinishImage1.gifgithub 源码地址:https://github.com/Milk-Fun/Hook-animation
工作中可能会需要我们实现一种类似于支付宝的完成动画,如下图:
使用
- ZFinishImage
其中circleR是圆的半径,高度和宽度最好定义为circleR的2倍或者定义为wrap会更好的显示。
<com.milkz.zfinishimage.ZFinishImage
android:id="@+id/ZFinishImage"
android:layout_width="100dp"
android:layout_height="100dp"
app:circleR="50dp" />
- 自定义属性
属性 | 含义 |
---|---|
circleR | 圆的半径,默认30dp |
colorCircle | 圆的颜色,默认蓝色 |
colorMark | 对勾颜色,默认白色 |
colorBG | 圆形之外的背景色,默认透明 |
animTime | 动画持续时间,默认2000ms |
widthHook | 对勾宽度,默认自动适配,如没有需求,最好不要修改 |
startWhenInit | 是否手动控制动画,false表示否,手工控制开始打开。true表示是,UI显示出来即表示开始动画。 |
- ZFinishImage1
<com.milkz.zfinishimage.ZFinishImage1
android:layout_width="100dp"
android:layout_height="100dp"
app:z1CircleR="50dp" />
- 自定义属性
属性 | 含义 |
---|---|
z1CircleR | 圆的半径,默认30dp |
z1ColorCircle | 圆的颜色,默认蓝色 |
z1ColorMark | 对勾颜色,默认白色 |
z1ColorBG | 圆形之外的背景色,默认透明 |
z1AnimTime | 动画持续时间,默认2000ms |
z1WidthHook | 对勾宽度,默认自动适配,如没有需求,最好不要修改 |
z1StartWhenInit | 是否手动控制动画,false表示否,手工控制开始打开。true表示是,UI显示出来即表示开始动画。 |
z1ColorCircleStoke | 最外圈圆框的颜色 |
设计思路
以ZFinishImage为例,
自定义UI动画实现。在View中绘制圆形和对勾,然后将整个过程加上动画。
具体实现
首先这个动画可以分解为两步,第一步化圆,第二步在圆中化对勾。
所以我们动画定义过程长度为0-2,0-1绘制圆,1-2绘制对勾,代码如下:
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 2);
valueAnimator.setDuration(durationTime);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
fraction = (float) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.start();
初始化时候,定义圆和对勾。
Path pathCirCle = new Path();
pathCirCle.addCircle(privateX, privateY, r, Path.Direction.CCW);
pathCirCle.moveTo(privateX - r / 2 - strokeWidth, privateY);
pathCirCle.lineTo(privateX - strokeWidth, privateY + r / 2);
pathCirCle.lineTo(privateX + 2 * r / 3, privateY - 1 * r / 3);
pathOk = new Path();
pathOk2 = new Path();
pathMeasure.setPath(pathCirCle, false);
ondraw绘画时候,根据不同进度绘画不同对象。
if (fraction <= 1) {
float len = pathMeasure.getLength();
float et = len * fraction;
pathMeasure.getSegment(0, et, pathOk, true);
} else {
if (ifFirst) {
ifFirst = false;
pathMeasure.nextContour();
}
float len = pathMeasure.getLength();
float et = len * (fraction - 1);
pathMeasure.getSegment(0, et, pathOk2, true);
}
canvas.drawPath(pathOk, paint);
canvas.drawPath(pathOk2, paint2);
详细代码请参考GitHub源码。
网友评论