Hencoder學(xué)習(xí)筆記1-7

【HenCoder Android 開發(fā)進(jìn)階】自定義 View 1-7:屬性動畫(進(jìn)階篇)

針對特殊類型的屬性來做屬性動畫;
針對復(fù)雜的屬性關(guān)系來做屬性動畫。

TypeEvaluator

TypeEvaluator 最經(jīng)典的用法是使用 ArgbEvaluator 來做顏色漸變的動畫。

ObjectAnimator animator = ObjectAnimator.ofInt(view, "color", 0xffff0000, 0xff00ff00);
animator.setEvaluator(new ArgbEvaluator());
animator.start();

自定義 Evaluator

// 自定義 HslEvaluator
private class HsvEvaluator implements   TypeEvaluator<Integer> {
 float[] startHsv = new float[3];
 float[] endHsv = new float[3];
 float[] outHsv = new float[3];

@Override
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
   // 把 ARGB 轉(zhuǎn)換成 HSV
   Color.colorToHSV(startValue, startHsv);
   Color.colorToHSV(endValue, endHsv);

   // 計算當(dāng)前動畫完成度(fraction)所對應(yīng)的顏色值
   if (endHsv[0] - startHsv[0] > 180) {
       endHsv[0] -= 360;
   } else if (endHsv[0] - startHsv[0] < -180) {
       endHsv[0] += 360;
   }
   outHsv[0] = startHsv[0] + (endHsv[0] - startHsv[0]) * fraction;
   if (outHsv[0] > 360) {
       outHsv[0] -= 360;
   } else if (outHsv[0] < 0) {
       outHsv[0] += 360;
   }
   outHsv[1] = startHsv[1] + (endHsv[1] - startHsv[1]) * fraction;
   outHsv[2] = startHsv[2] + (endHsv[2] - startHsv[2]) * fraction;

   // 計算當(dāng)前動畫完成度(fraction)所對應(yīng)的透明度
   int alpha = startValue >> 24 + (int) ((endValue >> 24 - startValue >> 24) * fraction);

   // 把 HSV 轉(zhuǎn)換回 ARGB 返回
   return Color.HSVToColor(alpha, outHsv);
 }
}

ObjectAnimator animator = ObjectAnimator.ofInt(view, "color", 0xff00ff00);
// 使用自定義的 HslEvaluator
animator.setEvaluator(new HsvEvaluator());
animator.start();

借助于 TypeEvaluator,屬性動畫就可以通過 ofObject() 來對不限定類型的屬性做動畫了。方式很簡單:

為目標(biāo)屬性寫一個自定義的 TypeEvaluator
使用 ofObject() 來創(chuàng)建 Animator,并把自定義的 TypeEvaluator 作為參數(shù)填入

PropertyValuesHolder 同一個動畫中改變多個屬性

PropertyValuesHolder holder1 = PropertyValuesHolder.ofFloat("scaleX", 1);
PropertyValuesHolder holder2 = PropertyValuesHolder.ofFloat("scaleY", 1);
PropertyValuesHolder holder3 = PropertyValuesHolder.ofFloat("alpha", 1);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder1, holder2, holder3)
animator.start();

AnimatorSet 多個動畫配合執(zhí)行

ObjectAnimator animator1 = ObjectAnimator.ofFloat(...);
animator1.setInterpolator(new LinearInterpolator());
ObjectAnimator animator2 = ObjectAnimator.ofInt(...);
animator2.setInterpolator(new DecelerateInterpolator());

AnimatorSet animatorSet = new AnimatorSet();
// 兩個動畫依次執(zhí)行
animatorSet.playSequentially(animator1, animator2);
// 兩個動畫同時執(zhí)行
animatorSet.playTogether(animator1, animator2);
// 使用       AnimatorSet.play(animatorA).with/before/after(animatorB)
// 的方式來精確配置各個 Animator 之間的關(guān)系
animatorSet.play(animator1).with(animator2);
animatorSet.play(animator1).before(animator2);
animatorSet.play(animator1).after(animator2);
animatorSet.start();

PropertyValuesHolders.ofKeyframe() 把同一個屬性拆分

// 在 0% 處開始
Keyframe keyframe1 = Keyframe.ofFloat(0, 0);
// 時間經(jīng)過 50% 的時候,動畫完成度 100%
Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 100);
// 時間見過 100% 的時候,動畫完成度倒退到 80%,即反彈 20%
Keyframe keyframe3 = Keyframe.ofFloat(1, 80);
PropertyValuesHolder holder =   PropertyValuesHolder.ofKeyframe("progress", keyframe1, keyframe2, keyframe3);

ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, holder);
animator.start();

「關(guān)于復(fù)雜的屬性關(guān)系來做動畫」,就這么三種:

1.使用 PropertyValuesHolder 來對多個屬性同時做動畫;
2.使用 AnimatorSet 來同時管理調(diào)配多個動畫;
3.PropertyValuesHolder 的進(jìn)階使用:使用 PropertyValuesHolder.ofKeyframe() 來把一個屬性拆分成多段,執(zhí)行更加精細(xì)的屬性動畫。

ValueAnimator 最基本的輪子

遵循一個原則就行:盡量用簡單的。能用 View.animate() 實(shí)現(xiàn)就不用 ObjectAnimator,能用 ObjectAnimator 就不用 ValueAnimator。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容