仿支付寶完成動畫
github 源碼地址:https://github.com/Milk-Fun/Hook-animation
????工作中可能會需要我們實現(xiàn)一種類似于支付寶的完成動畫,如下圖:
使用
- 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 | 動畫持續(xù)時間柄粹,默認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 | 動畫持續(xù)時間,默認2000ms |
z1WidthHook | 對勾寬度菊匿,默認自動適配付呕,如沒有需求,最好不要修改 |
z1StartWhenInit | 是否手動控制動畫跌捆,false表示否徽职,手工控制開始打開。true表示是佩厚,UI顯示出來即表示開始動畫姆钉。 |
z1ColorCircleStoke | 最外圈圓框的顏色 |
設(shè)計思路
????以ZFinishImage為例,
自定義UI動畫實現(xiàn)。在View中繪制圓形和對勾育韩,然后將整個過程加上動畫克蚂。
具體實現(xiàn)
????首先這個動畫可以分解為兩步,第一步化圓筋讨,第二步在圓中化對勾埃叭。
????所以我們動畫定義過程長度為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繪畫時候类早,根據(jù)不同進度繪畫不同對象。
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源碼嗜逻。