最近項(xiàng)目大改, 忙里偷閑 記錄一下項(xiàng)目里用到的加載動(dòng)畫妓羊。胯究。。躁绸。裕循。
開始了:
UI大佬甩手扔過來一張GIF 說 : 我要這個(gè)效果。
........這 得加錢净刮。剥哑。。
好吧 先看看這張動(dòng)圖:
既然活都接下了淹父,只能硬著頭皮上了株婴。。
對(duì)于這個(gè)稍微復(fù)雜一點(diǎn)的動(dòng)畫暑认,當(dāng)然得先拆分一下困介,分成簡(jiǎn)單的動(dòng)畫后逐一實(shí)現(xiàn),
看到這張動(dòng)圖穷吮,它一共包含三中動(dòng)畫效果
1.整體旋轉(zhuǎn)
2.線條長(zhǎng)短變化
3.縮放
既然已經(jīng)拆分出來了逻翁,就可以一個(gè)一個(gè)實(shí)現(xiàn)了。捡鱼。八回。
1.線條長(zhǎng)短變化
這里我使用的是canvas.drawArc 繪制圓弧的方式實(shí)現(xiàn)的, 也可以用path的方式實(shí)現(xiàn)驾诈,
這里圓弧分為兩半缠诅,中間間距我設(shè)置為20,可以得到一個(gè)圓弧的弧度是160.
添加屬性動(dòng)畫乍迄, 讓線條開始長(zhǎng)短變化
比較簡(jiǎn)單管引, 看一下代碼:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
arcRectF.set(paintStork, paintStork, getWidth() - paintStork, getHeight() - paintStork);
//第一個(gè)圓弧
canvas.drawArc(arcRectF, 270 + (intervalRadian >> 1), radian * progress, false, paint);
//第二個(gè)圓弧
canvas.drawArc(arcRectF, 90 + (intervalRadian >> 1), radian * progress, false, paint);
if(!isStart){
startAnim();
isStart = true;
}
}
private void startAnim(){
valueAnimator = ValueAnimator.ofFloat(minRadian, 1f);
valueAnimator.setDuration(rotatTime);
valueAnimator.setRepeatMode(ValueAnimator.REVERSE);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
progress = (float) animation.getAnimatedValue();
postInvalidate();
}
});
valueAnimator.start();
}
通過不斷更新progress加上重繪,實(shí)現(xiàn)了圓弧的長(zhǎng)短變化闯两。
2.旋轉(zhuǎn)
這部分如果用canvas實(shí)現(xiàn)的話 的不斷更新圓弧的起始位置褥伴,相對(duì)于整個(gè)view的旋轉(zhuǎn)來說復(fù)雜一點(diǎn),
所以我選擇整個(gè)view的旋轉(zhuǎn)漾狼, 為view添加一個(gè)普通的旋轉(zhuǎn)動(dòng)畫
看一下代碼:
private void startRotatWithScale() {
// 利用 ObjectAnimator 實(shí)現(xiàn)旋轉(zhuǎn)動(dòng)畫
final AnimatorSet rotateAnimationSet = new AnimatorSet();
rotationAnimator = ObjectAnimator.ofFloat(this, "rotation",0, 360);
rotationAnimator.setDuration(rotatTime);
rotationAnimator.setInterpolator(new LinearInterpolator());
rotationAnimator.setRepeatCount(ValueAnimator.INFINITE);
rotationAnimator.setRepeatMode(ValueAnimator.RESTART);
rotateAnimationSet.playTogether(
rotationAnimator
);
rotateAnimationSet.start();
現(xiàn)在就差一個(gè)縮放動(dòng)畫了重慢。
3.縮放動(dòng)畫
這個(gè)縮放和普通的縮放不同,它每轉(zhuǎn)三圈才縮放一次逊躁,這個(gè)不是很好控制似踱,如果用計(jì)時(shí)器來就顯得很冗余了,好在google給我們提供了關(guān)鍵幀動(dòng)畫, 通過關(guān)鍵幀動(dòng)畫核芽, 可以控制縮放的時(shí)間段囚戚,這就很好弄了:
看一下代碼:
Keyframe keyframe1 = Keyframe.ofFloat(0f, 1.0f);
Keyframe keyframe2 = Keyframe.ofFloat(0.9f, 1.0f);
Keyframe keyframe3 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder frameHodlerX = PropertyValuesHolder.ofKeyframe("scaleX",keyframe1,keyframe2,keyframe3);
animatorX = ObjectAnimator.ofPropertyValuesHolder(this, frameHodlerX);
animatorX.setDuration(scaleTime);
animatorX.setRepeatCount(ValueAnimator.INFINITE);
animatorX.setRepeatMode(ValueAnimator.REVERSE);
animatorX.start();
PropertyValuesHolder frameHodlerY = PropertyValuesHolder.ofKeyframe("scaleY",keyframe1,keyframe2,keyframe3);
animatorY = ObjectAnimator.ofPropertyValuesHolder(this, frameHodlerY);
animatorY.setDuration(scaleTime);
animatorY.setRepeatCount(ValueAnimator.INFINITE);
animatorY.setRepeatMode(ValueAnimator.REVERSE);
animatorY.start();
這樣三個(gè)動(dòng)畫組合起來就實(shí)現(xiàn)了我想要的效果了:
see see
看上去還不錯(cuò)。轧简。驰坊。。