Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android動畫全解,Android動畫

Android動畫全解,Android動畫

編輯:關於android開發

Android動畫全解,Android動畫


在Android開發中經常會碰到動畫,看到別的應用有很酷炫的應用時,總是想怎麼去實現,但是每次都是發現感覺是知道怎麼做的,實際做起來還是無從下手的感覺,究其原因還是

Android動畫方面的知識不全面,這幾天利用空閒時間研究了下Android動畫知識,當作學習日記,大家也好有所借鑒。

Android主要分三類動畫:Tween Animation、Frame Animation、Property Animation。

其中Tween Animation、Frame Animation是在Android是在Android3.0之前就有的動畫技術,後來由於動畫需求越來越高,Tween Animation、Frame Animation已經滿足不了應用對於動畫效果的需求了,於是在Android3.0之後,谷歌又增加了新的動畫Property Animation。下面對這三種動畫逐個介紹。

 

一、Tween Animation

中文亦叫補間動畫,它是通過平移、旋轉、縮放以及修改透明度來達到動畫效果的,原理是給出兩個關鍵幀,通過一些算法將給定屬性值在給定時間內在兩個關鍵幀間漸變。這裡我們只關心動畫的使用,不關注它的代碼實現。Tween Animation基於Animation類擴展,有以下幾個Tween Animation類:TranslateAnimation(平移)、AlphaAnimation(透明度)、ScaleAnimation(縮 放)、RotateAnimation(旋轉)。

TranslateAnimation使用方法如下:

復制代碼
private TranslateAnimation mTranslateAnimation;
//這四個參數含義分別是當前View x起點坐標、x終點坐標、y起點坐標、y終點坐標
mTranslateAnimation = new TranslateAnimation(0, 200, 0, 0);
//動畫持續時間
mTranslateAnimation.setDuration(2000);
//重復次數
mTranslateAnimation.setRepeatCount(1);
//動畫執行模式
mTranslateAnimation.setRepeatMode(Animation.REVERSE);
復制代碼

以上代碼含義為從view的起點開始,保持y軸不變,沿著x平移200個像素,平移時間為2秒,重復執行一次,第二次執行方式與第一次執行方式完全相反,如下圖:

以上是java代碼實現的方式,亦可以使用xml實現,如下:

/res/anim/translate.xml

復制代碼
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:toXDelta="200"
        android:fromYDelta="0"
        android:toYDelta="0"
        android:duration="2000"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
</set>
復制代碼

fromXDelta:View x軸起點

toXDelta:View x軸終點

fromYDelta:View y軸起點

toYDelta:View y軸終點

duration:動畫持續時間

repeatCount:動畫執行次數

repeatMode:動畫執行模式

interpolator:插值器,可以理解為View動畫值的改變規律

java中調用:

private Animation mTranslateAnimation;
mTranslateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate);
mTranslateIv.startAnimation(mTranslateAnimation);

使用Java或者xml實現動畫並無什麼不同,采用哪種完全取決於自己的編程習慣,但如果單純從擴展性來說,顯然xml方式更占優。

AlphaAnimation使用方法如下:

private AlphaAnimation mAlphaAnimation;
//不透明度從100%到0
mAlphaAnimation = new AlphaAnimation(1, 0);
mAlphaAnimation.setDuration(2000);
mAlphaAnimation.setRepeatCount(1);
mAlphaAnimation.setRepeatMode(Animation.REVERSE);

以上代碼含義是在2秒內將View的不透名度從1變為0,總共執行2次,第一次和第二次執行動畫過程相反,效果如下圖:

xml實現方法可參照TranslateAnimation

ScaleAnimation使用方法如下:

mScaleAnimation = new ScaleAnimation(1, 2, 1, 2);
mScaleAnimation.setDuration(2000);
mScaleAnimation.setRepeatCount(1);
mScaleAnimation.setRepeatMode(Animation.REVERSE);

上面ScaleAnimation構造函數中四個參數分別是:

fromX:起始x方向大小

toX:最終x方向大小

fromY:起始y坐標

toY:最終y坐標

上面代碼含義為將View在2秒內橫豎方向增大一倍,第二次是在原來的基礎上縮小一倍,效果圖如下:

xml實現方法同參照TranslateAnimation

RotateAnimation使用方法如下:

mRotateAnimation = new RotateAnimation(0, 360);
mRotateAnimation.setDuration(2000);
mRotateAnimation.setRepeatCount(1);
mRotateAnimation.setRepeatMode(Animation.REVERSE);

上面代碼含義為在2秒內將View旋轉360度,再旋轉回來,效果如下:

 

二、Frame Animation

看過電影的人也許知道,電影是由一張一張圖片組成的,只不過圖片切換速度快,在人視覺中看到的是連續效果。Frame Animation亦同樣基於此原理實現,事先准備幾張圖片,按特定的順序排好,然後使用特定的動畫類將其播放,基於這種動畫實現方式,Frame Anmation亦有一個中文名:逐幀動畫。

實現這種動畫需要使用到AnimationDrawable類,它繼承於Drawable,使用方式如下:

復制代碼
private AnimationDrawable mAnimationDrawable;
mAnimationDrawable = new AnimationDrawable();
//增加圖片,並設定圖片播放時間
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.australia), 500);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.austria), 500);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.china), 500);
mAnimationDrawable.start();
復制代碼

上面代碼是將三張圖片按照指定的順序,指定的時間播放,以達到動畫效果,如下圖:

同樣亦可以使用xml方式實現,代碼如下:

/anim/frame.xml

復制代碼
<?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/australia" android:duration="500"/>
    <item android:drawable="@drawable/austria" android:duration="500"/>
    <item android:drawable="@drawable/china" android:duration="500"/>
</animation-list>
復制代碼

xml中調用:

<ImageView
        android:id="@+id/frame_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@anim/frame"/>

java中調用:

private ImageView mFrameIv;
private AnimationDrawable mAnimationDrawable;
mFrameIv = (ImageView) findViewById(R.id.frame_iv);
mAnimationDrawable = (AnimationDrawable) mFrameIv.getBackground();
mAnimationDrawable.start();

關於Frame Tween的知識比較簡單,熟悉AnimationDrawable便行,下面介紹本章最重要的Property Animation。

 

三、Property Animation

中文亦叫屬性動畫,如其名字一樣,可以改變對象的屬性,注意是對象,不是View,而且是任意對象,只要對象符合一定條件即可,上述中的Tween Animation僅僅只能操作View,對於View之外的對象則無能為力,並且其未改變View的屬性,僅僅是通過父類View對其重繪達到動畫效果;而Frame Animation動畫功能則過於簡單。隨著我們Android應用的發展,能發現Tween Animation、Frame Animation有時候並不能達到理想的效果,谷歌亦意識到了這點,故而在Android3.0之後增加了強大的屬性動畫。

Property Animation有兩個類可供使用:ValueAnimator、ObjectAnimator。這兩個類均直接或間接繼承於Animator

ObjectAnimator使用方式如下:

復制代碼
private ObjectAnimator mObjectAnimator;
//設置不透明度從1到0變化
mObjectAnimator = ObjectAnimator
                .ofFloat(mObjectAnimatorIv, "alpha", 1, 0)
                .setDuration(1000);
//設置插值器,先加速後減速
mObjectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
//動畫重復執行一次
mObjectAnimator.setRepeatCount(1);
//設置執行模式
mObjectAnimator.setRepeatMode(ValueAnimator.REVERSE);
mObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        //獲取當前的動畫值
        float cVal = (Float) animation.getAnimatedValue();
        //根據動畫值縮放當前View
        mObjectAnimatorIv.setScaleX(cVal);
        mObjectAnimatorIv.setScaleY(cVal);
    }
});
復制代碼

上面代碼意思是將當前View不透明度從1按照一定規律變為0,第一句代碼中的ofFloat(mObjectAnimatorIv, "alpha", 1, 0)中的alpha代表不透明度,有人可能會說我可以寫其他的嗎?當然可以,比如寫成ofFloat(mObjectAnimatorIv, "tmg", 1, 0),但你會發現動畫執行後不會有效果,因為寫這個字符串的前提是當前View或者當前View的父類中實現了這個字符串的get、set方法,即getAlpha、setAlpha,當動畫執行時,動畫類會通過調用setAlpha來改變View的alpha屬性,達到想要的動畫效果。那這個alpha是怎麼從1便到0的呢?Property Animation中有一個TypeEvaluator,這個屬性的含義是根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出當前時間的屬性值,上例中的alpha便是這樣從1變到0的,但是上面並沒設置TypeEvaluator啊?其原因是Property Animation

會配置一個默認的TypeEvaluator,如果一定要顯性設置,有幾個寫好的TypeEvaluator供選擇:

IntEvaluator:屬性值的類型為int

FloatEvaluator:屬性值的類型為float

ArgbEvaluator:屬性的值類型為十六進制顏色值

如果上述沒有你需要的TypeEvaluator,你亦可以選擇繼承TypeEvaluator自定義一個類似的TypeEvaluator

從上面代碼中我們還可以看到:

float cVal = (Float) animation.getAnimatedValue();
mObjectAnimatorIv.setScaleX(cVal);
mObjectAnimatorIv.setScaleY(cVal);

其中animation.getAnimatedValue();是計算View當前屬性值,當然根據前面的設置,這個屬性值實在1到0之間變化,下面的兩行代碼是通過每個時刻不同的屬性值對View進行縮放,達到在改變透明度的同時,

又改變View大小的效果,效果圖如下:

同樣的,Property Animation也可以通過xml實現,類似上面兩種,不再介紹,讀者可從之後分享的源碼中看到

ValueAnimator的使用方式和ObjectAnimator很相似,唯一的區別是ValueAnimator不能直接設置屬性,即類似

mObjectAnimator = ObjectAnimator
                .ofFloat(mObjectAnimatorIv, "alpha", 1, 0)
                .setDuration(1000);

它只能這樣:

mValueAnimator = ValueAnimator.ofFloat(1, 0);
mValueAnimator.setTarget(mValueAnimatorIv);

動畫效果可在監聽事件中實現,如:

復制代碼
mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float animatedValue = (float) animation.getAnimatedValue();
        mValueAnimatorIv.setAlpha(animatedValue);
        mValueAnimatorIv.setScaleX(animatedValue);
        mValueAnimatorIv.setScaleY(animatedValue);
    }
});
復制代碼

談談Keyframe,keyframe是一個時間/值對,通過它可以定義一個在特定時間的特定狀態,

即關鍵幀,而且在兩個keyframe之間可以定義不同的Interpolator,就好像多個動畫的拼接,第一個動畫的結束點是第二個動畫的開始。keyframe是抽象類,要通過ofInt(),ofFloat()等獲得適當的keyframe,然後通過PropertyValuesHolder.ofKeyframe

獲得PropertyValuesHolder對象,如下例子:

復制代碼
Keyframe kf0 = Keyframe.ofInt(0, 400);
Keyframe kf1 = Keyframe.ofInt(0.25f, 200);
Keyframe kf2 = Keyframe.ofInt(0.5f, 400);
Keyframe kf3 = Keyframe.ofInt(0.75f, 100);
Keyframe kf4 = Keyframe.ofInt(1f, 500);
PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf3, kf4);
mKeyframesObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(mKeyframesObjectAnimationBtn, propertyValuesHolder);
mKeyframesObjectAnimator.setDuration(2000);
mKeyframesObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        android.util.Log.d("update", (animation.getAnimatedValue()).toString());
    }
});
復制代碼

動畫效果同樣是在onAnimationUpdate中添加,上面僅僅是打個log

如果你想應用多個動畫,AnimationSet可以幫到你,AnimationSet提供了一個把多個動畫組合成一個組合的機制,並可設置組中動畫的時序關系,如同時播放,順序播放等。

如下代碼:

mAnimatorSet = new AnimatorSet();
mAnimatorSet.play(mObjectAnimator).before(mValueAnimator);
mAnimatorSet.play(mValueAnimator).before(mKeyframesObjectAnimator);

play是播放,before是在當前動畫之前播放,還有2個方法with、after,分別是與當前動畫同時播放,在當前動畫之後播放,效果如下:

上面是三個動畫按照一定順序播放,有時候我們需要比較復雜的動畫效果時,這個類會很重要。

 

四、擴展介紹

interpolator:插值器,代表動畫值的變化速度

repeatCount:動畫重復執行的次數

repeatMode:動畫執行模式,每次動畫執行方式是一樣還是按照相反方向執行

duration:動畫執行時間

evaluator:根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出當前時間的屬性值

 

參考文章:

http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html

http://blog.csdn.net/lmj623565791/article/details/38092093

源碼:

https://github.com/taothreeyears/animation

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved