屬性動畫
01 屬性動畫背景
屬性動畫出現之前,有幀動畫和View動畫
- 幀動畫(FrameAnimation)就是將一個動畫分成多個幀。有點類似膠捲電影。
- View動畫最大的缺點就是不具有互動性。相應器和View動畫脫離。優點是效率高。
為了實現更豐富的動畫效果,Google推出了屬性動畫。
02 屬性動畫涉及的類
類 | 描述 |
---|---|
ObjectAnimator | 屬性動畫最重要的類了 |
ObjectAnimator.ofFloat(動畫View,"屬性",值) |
|
ValueAnimator | 這個有點類似於幀動畫 |
Animator.AnimatorListener | 監聽動畫 開始,結束,取消,重複 |
AnimatorListenerAdapter | 選擇性監聽 |
2.1Class ObjectAnimator
比如要實現View的X軸方向平移200px
ObjectAnimator ani = ObjectAnimator.ofFloat(view,"translationX",200); ani.setDuration(300); // 設定動畫持續時間 ani.start();
注意:屬性動畫通過反射實現的。說白的比如你的動畫要調整View的高度,那麼你的View要有 getHeight()
方法。如果沒有的話可以使用包裝類。
2.2 Class ValueAnimator
舉個栗子:實現類似於LED燈的橫幅效果

載入慢LED.gif
// Fragment 類中程式碼 public void initView(View view) { final ImageView v = view.findViewById(R.id.view_movable); // 設定水平滑動的範圍 ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, getResources().getDisplayMetrics().widthPixels - v.getLayoutParams().width); valueAnimator.setTarget(v); valueAnimator.setRepeatCount(-1); //重複次數 ,-1 表示無限迴圈 valueAnimator.setRepeatMode(ValueAnimator.REVERSE); valueAnimator.setDuration(2000); // 一次動畫的時間長度 valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float f = (float) animation.getAnimatedValue(); ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams(); params.leftMargin = (int) f; v.setLayoutParams(params); System.err.print(f); } }); valueAnimator.start(); // 開始動畫 }
2.3 AnimatorListener 動畫監聽
valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { Log.d("fragment","動畫片要要開始了"); } @Override public void onAnimationEnd(Animator animation) { Log.d("fragment","動畫GG"); } @Override public void onAnimationCancel(Animator animation) { Log.d("fragment","動畫被取消了,讓我們做一些有趣的事情吧"); } @Override public void onAnimationRepeat(Animator animation) { Log.d("fragment","再看一片動畫"); } }); // 要覆蓋的方法太多 怎麼辦呢? 看下面 valueAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); } });
2.4 Class AnimatorSet 組合動畫
四個方法
after(Animator anim) after(long delay) before(Animator anim) with(Animator anim)
// 我感覺幾個api解釋起來比較拗口,直接看下面的play函式 Animator animator1 = ObjectAnimator.ofFloat(v,"translationX",0.0f,200f,0f); Animator animator2 = ObjectAnimator.ofFloat(v,"scaleX",1.0f,2.0f); Animator animator3 = ObjectAnimator.ofFloat(v,"rotationX",0.0f,90.0f,0.0f); AnimatorSet set = new AnimatorSet(); set.setDuration(1000); set.play(animator1).with(animator2).after(animator3); // 從英語的角度,很容易讀懂上面這一行程式碼,先3再1,2同時 set.start();
Class PropertyValuesHolder 組合動畫和Class Animator區別在於動畫的執行沒有先後順序
3 在XML中使用屬性動畫
動畫設計到的屬性都太多了,把它定義在xml可以減少程式碼數量,而且可以複用。
- 在res資料夾下建立animator資料夾,cd進去建立anim.xml 檔案
- 下面是一個動畫的例子
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:layout_width="wrap_content" android:layout_height="wrap_content" android:duration="3000" android:propertyName="scaleX" android:valueFrom="1" android:valueTo="2" android:valueType="floatType"> </objectAnimator> </set>
- 程式碼中呼叫
Animator animator = AnimatorInflater.loadAnimator(this ,R.animator.anim); animator.setTarget(v); animator.start();