Android 動畫
Android的動畫分為了三種, 分別是 幀動畫、View動畫(補間動畫)、屬性動畫。
1、幀動畫
幀動畫就是順序播放一組預先定義好的圖片,就類似於我們觀看視訊,就是一張一張的圖片連續播放。
幀動畫的使用很簡單,總共就兩個步驟:
- 1、在res/drawable目錄下定義一個XML檔案,根節點為系統提供的animation-list,然後放入定義更好的圖片;
- 2、使用AnimationDrawable類播放第一步定義好的Drawable中的圖片,形成動畫效果;
程式碼示例,第一步,建立Drawable檔案,放在res/rawable目錄下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/image01" android:duration="500"/> <item android:drawable="@drawable/image02" android:duration="500"/> <item android:drawable="@drawable/image03" android:duration="500"/> </animation-list>
上述xml中,有些屬性我們要了解到:
- 1、android:oneshot=“false”: 表示是否重複播放動畫,還是隻播放一次;
- 2、每個item都有Drawable和duration屬性,Drawable表示我們要播放的圖片;duration表示這張圖播放的時間;
程式碼示例,第二步,用AnimationDrawable播放動畫:
Button button = (Button) findViewById(R.id.bt_001); button.setBackgroundResource(R.drawable.frame_animation);//把Drawable設定為button的背景 //拿到這個我們定義的Drawable,實際也就是AnimationDrawable AnimationDrawable animationDrawable = (AnimationDrawable) button.getBackground(); animationDrawable.start();//開啟動畫
2、View動畫(也稱補間動畫)
2.1 View動畫的基本介紹
view動畫也稱為補間動畫,因為我們只需要拿到一個view,設定它開始和結束的位置,中間的view會自動由系統補齊,而不需要幀動畫每一幅圖都是提前準備好的。
View動畫是Android一開始就提供的比較原始的動畫,主要支援四種效果:平移、縮放、旋轉、透明度變化(漸變) 四種基本效果,我們可以再這四種基礎效果的基礎上,選擇其中的幾種進行組合。
View動畫的四種基本效果對應了四個Animation的子類,如下:
比如建立一個平移動畫translate_animation.xml, 也是需要把xml檔案放在res/anim目錄下:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="0"/>
scale_animation.xml :
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"/>
pivotX和pivotY表示以縮放中心的位置。
rotate_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegree="0"
android:toDegree="1800"
android:pivotX = "50%"
android:pivotY="50%"
android:duration = "3000"
/>
漸變動畫alpha_animation.xml:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromAlpha="1.0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toAlpha="0.0" />
interpolator表示動畫插值器, 可以控制動畫的變化速率, 比如前200ms很慢,中間600ms很快,最後200ms又很慢。
pivot 這個屬性主要是在translate 和 scale 動畫中,這兩種動畫都牽扯到view 的“物理位置“發生變化,所以需要一個參考點。而pivotX和pivotY就共同決定了這個點;它的值可以是float或者是百分比數值。
以 pivotX 為例,說明其取不同的值的含義:
- 10:距離動畫所在view自身左邊緣10畫素
- 10% :距離動畫所在view自身左邊緣 的距離是整個view寬度的10%
- 10%p:距離動畫所在view父控制元件左邊緣的距離是整個view寬度的10%
在Activity中使用動畫:
Animation animation = AnimationUtils.loadAnimation(MainActivity.this,R.anim.rotate_animation);
textView.startAnimation(animation);
除了用xml來設定View動畫,也可以用程式碼直接搞定,如
Animation translateAnimation = new TranslateAnimation(0,500,0,500);
// 建立平移動畫的物件:平移動畫對應的Animation子類為TranslateAnimation
// 引數分別是:
// 1. fromXDelta :檢視在水平方向x 移動的起始值
// 2. toXDelta :檢視在水平方向x 移動的結束值
// 3. fromYDelta :檢視在豎直方向y 移動的起始值
// 4. toYDelta:檢視在豎直方向y 移動的結束值
translateAnimation.setDuration(3000);
// 播放動畫直接 startAnimation(translateAnimation)
//如:
mButton.startAnimation(translateAnimation);
2.2 View動畫的組合動畫–AnimationSet
我們可以使用AnimationSet把View動畫的平移、縮放、旋轉、漸變都揉在一起,也是既能通過程式碼實現,也可以通過xml實現
xml實現:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
>
<scale
android:duration="3000"
android:fromXScale="0.0"
android:fromYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:toXScale="1.0"
android:toYScale="1.0"/>
<alpha
android:duration="3000"
android:fromAlpha="1.0"
android:toAlpha="0.5" />
<rotate
android:fromDegrees="0"
android:toDegrees="720"
android:pivotX = "50%"
android:pivotY="50%"
android:duration = "3000"
/>
<translate
android:fromXDelta="0"
android:toXDelta="100"
android:fromYDelta="0"
android:toYDelta="100" />
</set>
程式碼實現:
AnimationSet setAnimation = new AnimationSet(true);
// 特別說明以下情況
// 因為在下面的旋轉動畫設定了無限迴圈(RepeatCount = INFINITE)
// 所以動畫不會結束,而是無限迴圈
// 所以組合動畫的下面兩行設定是無效的, 以後設定的為準
setAnimation.setRepeatMode(Animation.RESTART);
setAnimation.setRepeatCount(1);// 設定了迴圈一次,但無效
// 旋轉動畫
Animation rotate = new RotateAnimation(0,360,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotate.setDuration(1000);
rotate.setRepeatMode(Animation.RESTART);
rotate.setRepeatCount(Animation.INFINITE);
// 平移動畫
Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT,-0.5f,
TranslateAnimation.RELATIVE_TO_PARENT,0.5f,
TranslateAnimation.RELATIVE_TO_SELF,0
,TranslateAnimation.RELATIVE_TO_SELF,0);
translate.setDuration(10000);
// 透明度動畫
Animation alpha = new AlphaAnimation(1,0);
alpha.setDuration(3000);
alpha.setStartOffset(7000);
// 縮放動畫
Animation scale1 = new ScaleAnimation(1,0.5f,1,0.5f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
scale1.setDuration(1000);
scale1.setStartOffset(4000);
// 將建立的子動畫新增到組合動畫裡
setAnimation.addAnimation(alpha);
setAnimation.addAnimation(rotate);
setAnimation.addAnimation(translate);
setAnimation.addAnimation(scale1);
// 使用
mButton.startAnimation(setAnimation);
2.3 View動畫的使用場景
LayoutAnimation作用於ViewGroup,為ViewGroup指定一個動畫,然後,當它的子元素出場時都會具有這種效果。這種效果常用與ListView,有的ListView的每個item都以一定的動畫形式出現,就是用到的LayoutAnimation。
LayoutAnimation也是一個View動畫, 使用方式有三步:
- 1、定義LayoutAnimation的xml檔案;
- 2、指定具體的入場動畫;
- 3、為ViewGroup指定android:layoutAnimation屬性,引用這個LayoutAnimation的xml檔案;
第一步,定義LayoutAnimation的xml檔案:
// res/anim/anim_layout.xml
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"
android:animationOrder="normal"
android:animation="@anim/anim_item"/>
其中animationOrder有三種選項: normal、reverse、random。
第二步,指定具體動畫,也就是第一步中引用的anim_item:
// res/anim/anim_item.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:interpolator="@android:anim/accelerate_interpolator"
android:shareInterpolator="true" >
<alpha
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<translate
android:fromXDelta="500"
android:toXDelta="0" />
</set>
第三步,為ViewGroup指定android:layoutAnimation屬性:
<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/anim_layout"
android:background="#fff4f7f9"
android:cacheColorHint="#00000000"
android:divider="#dddbdb"
android:dividerHeight="1.0px"
android:listSelector="@android:color/transparent" />
這樣,ListView的每個item都具有了動畫效果。
除了用xml檔案,也同樣可以使用程式碼實現, 程式碼需要用到LayoutAnimationController:
ListView listView = (ListView) layout.findViewById(R.id.list);
Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_
item);
LayoutAnimationController controller = new LayoutAnimationController
(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);
2.4動畫的監聽
Animation.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animation animation) {
//動畫開始時執行
}
@Override
public void onAnimationRepeat(Animation animation) {
//動畫重複時執行
}
@Override
public void onAnimationCancel()(Animation animation) {
//動畫取消時執行
}
@Override
public void onAnimationEnd(Animation animation) {
//動畫結束時執行
}
});
場景二:Activity的切換效果
Activity有預設的切換效果,但是我們可以定製,主要用到overridePendingTransition(int enterAnima, int exitAnima)這個方法:
Intent intent = new Intent(this,TestActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
注意, 這個方法必須在startActivity或者finish方法之後呼叫才會生效。
場景三:Fragment的切換效果
可以使用FragmentTransaction的setCustomAnimation方法新增切換動畫。
3、屬性動畫
屬性動畫可以看作是增強版的補間動畫,與補間動畫的不同之處體現在:
- 補間動畫只能定義兩個關鍵幀在透明、旋轉、位移和傾斜這四個屬性的變換,但是屬性動畫可以定義任何屬性的變化。
- 補間動畫只能對 UI 元件執行動畫,但屬性動畫可以對任何物件執行動畫。
與補間動畫類似的是,屬性動畫也需要定義幾個方面的屬性:
- 動畫持續時間。預設為 300ms,可以通過 android:duration 屬性指定。
- 動畫插值方式。通過 android:interploator 指定。
- 動畫重複次數。通過 android:repeatCount 指定。
- 重複行為。通過 android:repeatMode 指定。
- 動畫集。在屬性資原始檔中通過 <set …/> 來組合。
- 幀重新整理率。指定多長時間播放一幀。預設為 10 ms。
屬性動畫 API
- Animator: 提供建立屬性動畫的基類,基本不會直接使用這個類。
- ValueAnimator:屬性動畫用到的主要的時間引擎,負責計算各個幀的屬性值,基本上其他屬性動畫都會直接或間接繼承它;
- ObjectAnimator: ValueAnimator 的子類,對指定物件的屬性執行動畫。
- AnimatorSet:Animator 的子類,用於組合多個 Animator。
除了這些 API,屬性動畫還提供了一個 Evaluator ,用來控制屬性動畫如何計算屬性值。
- IntEvaluator:計算 int 型別屬性值的計算器。
- FloatEvaluator: 用於計算 float 型別屬性值的計算器。
- ArgbEvaluator: 用於計算十六進位制形式表示的顏色值的計算器。
- TypeEvaluator: 可以自定義計算器。
使用 ValueAnimator 建立動畫的步驟:
- 呼叫 ValueAnimator 的 ofInt()、ofFloat() 或者 ofObject() 靜態方法建立 ValueAnimator 例項。
- 呼叫 ValueAnimator 的 setXxx() 等方法設定持續時間,插值方式、重複次數等。
- 呼叫 ValueAnimator 的 start() 方法啟動動畫。
- 為 ValueAnimator 註冊 AnimatorUpdateListener 監聽器,在該監聽器中可以監聽 ValueAnimator 計算出來的值改變,並將這些值應用到指定物件上。
屬性動畫的一般使用:
定義屬性動畫和補間動畫等類似,有兩種方式:
- 使用 ValueAnimator 或者 ObjectAnimator 的靜態工廠方法建立動畫。
- 使用資原始檔來定義動畫。
屬性動畫的使用:
- 建立 ValueAnimator 或 ObjectAnimator 物件 —— 即可以從 XML 資原始檔載入該動畫也可以直接呼叫 ValueAnimator 或者 ObjectAnimator 的靜態工廠方法建立動畫。
- 根據需要為 Animator 物件設定屬性。
- 如果需要監聽 Animator 的動畫開始事件,動畫結束事件、動畫重複事件、動畫值改變事件,並根據事件提供響應處理程式碼,需要為Animator 物件設定監聽器。
- 如果有多個動畫需要同時播放,需要使用 AnimatorSet 組合這些動畫。
- 呼叫 Animator 物件的 start 啟動動畫。
程式碼示例:
private void startAnim() {
ObjectAnimator animator0 = ObjectAnimator.ofFloat(
mImageViews.get(0),//這裡傳入的是一個任意物件,此處是imageview物件
"alpha",
1F,
0.5F);
ObjectAnimator animator1 = ObjectAnimator.ofFloat(
mImageViews.get(1),
"translationY",
200F);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(
mImageViews.get(2),
"translationX",
200F);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(
mImageViews.get(3),
"translationY",
-200F);
ObjectAnimator animator4 = ObjectAnimator.ofFloat(
mImageViews.get(4),
"translationX",
-200F);
AnimatorSet set = new AnimatorSet();
set.setDuration(500);
set.setInterpolator(new BounceInterpolator());
set.playTogether(
animator0,
animator1,
animator2,
animator3,
animator4);
set.start();
mFlag = false;
}