Android動畫全解,Android動畫

來源:互聯網
上載者:User

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之後,Google又增加了新的動畫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%到0mAlphaAnimation = 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有時候並不能達到理想的效果,Google亦意識到了這點,故而在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

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.