動(dòng)畫基礎(chǔ)全面總結(jié)

動(dòng)畫分類:

逐幀動(dòng)畫(Frame)
補(bǔ)間動(dòng)畫(Tween)
屬性動(dòng)畫(Property)(Android 3.0以后引入)


幀動(dòng)畫

定義:由N張靜態(tài)圖片收集起來,然后我們通過控制依次顯示這些圖片,形成動(dòng)畫。

實(shí)現(xiàn)幀動(dòng)畫,需要利用AnimationDrawable

方法1. 編寫Drawable,然后代碼中調(diào)用start()以及stop()開始或停止播放動(dòng)畫;
方法2. 在Java代碼中創(chuàng)建逐幀動(dòng)畫,創(chuàng)建AnimationDrawable對(duì)象,然后調(diào)用addFrame(Drawable frame,int duration)向動(dòng)畫中添加幀,接著調(diào)用start()和stop();

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item
        android:drawable="@mipmap/img_miao1"
        android:duration="80" />
    <item
        android:drawable="@mipmap/img_miao2"
        android:duration="80" />
    <item
        android:drawable="@mipmap/img_miao3"
        android:duration="80" />
    ...
</animation-list>
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button btn_start;
    private Button btn_stop;
    private ImageView img_show;
    private AnimationDrawable anim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
        anim = (AnimationDrawable) img_show.getBackground();
    }

    private void bindViews() {
        btn_start = (Button) findViewById(R.id.btn_start);
        btn_stop = (Button) findViewById(R.id.btn_stop);
        img_show = (ImageView) findViewById(R.id.img_show);
        btn_start.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                anim.start();
                break;
            case R.id.btn_stop:
                anim.stop();
                break;
        }
    }
}

補(bǔ)間動(dòng)畫

定義:指定動(dòng)畫開始,以及動(dòng)畫結(jié)束“關(guān)鍵幀”,而動(dòng)畫變化的“中間幀”則由系統(tǒng)計(jì)算并補(bǔ)齊。

實(shí)現(xiàn)補(bǔ)間動(dòng)畫:在res目錄下新建anim文件夾,右鍵new-Animation Resource file,新建文件的根目錄都是set。
xml中,在其子節(jié)點(diǎn)中添加代碼。

Andoird所支持的補(bǔ)間動(dòng)畫效果有如下這五種(第五種是前面幾種的組合):

  • AlphaAnimation透明度漸變效果,創(chuàng)建時(shí)許指定開始以及結(jié)束透明度,還有動(dòng)畫的持續(xù)時(shí)間,透明度的變化范圍(0,1),0是完全透明,1是完全不透明;對(duì)應(yīng)<alpha/>標(biāo)簽;

  • ScaleAnimation縮放漸變效果,創(chuàng)建時(shí)需指定開始以及結(jié)束的縮放比,以及縮放參考點(diǎn),還有動(dòng)畫的持續(xù)時(shí)間;對(duì)應(yīng)<scale/>標(biāo)簽;

  • TranslateAnimation位移漸變效果,創(chuàng)建時(shí)指定起始以及結(jié)束位置,并指定動(dòng)畫的持續(xù)時(shí)間即可;對(duì)應(yīng)<translate/>標(biāo)簽;

  • RotateAnimation旋轉(zhuǎn)漸變效果,創(chuàng)建時(shí)指定動(dòng)畫起始以及結(jié)束的旋轉(zhuǎn)角度,以及動(dòng)畫持續(xù)時(shí)間和旋轉(zhuǎn)的軸心;對(duì)應(yīng)<rotate/>標(biāo)簽;

  • AnimationSet組合漸變,就是前面多種漸變的組合,對(duì)應(yīng)<set/>標(biāo)簽。

1)AlphaAnimation(透明度漸變)

<alpha xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromAlpha="1.0"  
    android:toAlpha="0.1"  
    android:duration="2000"/>  

屬性解釋:

fromAlpha :起始透明度
toAlpha:結(jié)束透明度
透明度的范圍為:0-1,完全透明-完全不透明

2)ScaleAnimation(縮放漸變)

<scale xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_interpolator"  
    android:fromXScale="0.2"  
    android:toXScale="1.5"  
    android:fromYScale="0.2"  
    android:toYScale="1.5"  
    android:pivotX="50%"  
    android:pivotY="50%"  
    android:fillAfter="false"
    android:duration="2000"/>  

屬性解釋:

fromXScale/fromYScale:沿著X軸/Y軸縮放的起始比例;
toXScale/toYScale:沿著X軸/Y軸縮放的結(jié)束比例;
以上四種屬性值: 0.0表示收縮到?jīng)]有,1.0表示正常無伸縮,值小于1.0表示收縮,值大于1.0表示放大;值為相應(yīng)倍數(shù)

pivotX/pivotY:縮放的中軸點(diǎn)X/Y坐標(biāo),即距離自身左邊緣的位置,比如50%就是以圖像的中心為中軸點(diǎn);
以上兩個(gè)屬性值:從0%-100%中取值,50%為物件的X或Y方向坐標(biāo)上的中點(diǎn)位置

3)TranslateAnimation(位移漸變)

anim_translate.xml

<translate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromXDelta="0"  
    android:toXDelta="320"  
    android:fromYDelta="0"  
    android:toYDelta="0"  
    android:duration="2000"/>   

屬性解釋:

fromXDelta/fromYDelta:動(dòng)畫起始位置的X/Y坐標(biāo);
toXDelta/toYDelta:動(dòng)畫結(jié)束位置的X/Y坐標(biāo);
pivotX/pivotY:表示旋轉(zhuǎn)動(dòng)作的參考點(diǎn),不設(shè)置表示默認(rèn)以自己為參照物;

4)RotateAnimation(旋轉(zhuǎn)漸變)

<rotate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromDegrees="0"  
    android:toDegrees="360"  
    android:duration="1000"  
    android:repeatCount="1"  
    android:repeatMode="reverse"/>  

屬性解釋:

fromDegrees/toDegrees:旋轉(zhuǎn)的起始/結(jié)束角度,當(dāng)角度為負(fù)數(shù)表示逆時(shí)針旋轉(zhuǎn),當(dāng)角度為正數(shù)表示順時(shí)針旋轉(zhuǎn)
repeatCount:旋轉(zhuǎn)的次數(shù),默認(rèn)值為0,代表一次,假如是其他值,比如3,則旋轉(zhuǎn)4次。另外,值為-1或者infinite時(shí),表示動(dòng)畫永不停止
repeatMode:設(shè)置重復(fù)模式,默認(rèn)restart,但只有當(dāng)repeatCount大于0或者infinite或-1時(shí)才有效。還可以設(shè)置成reverse,表示偶數(shù)次顯示動(dòng)畫時(shí)會(huì)做方向相反的運(yùn)動(dòng)!

5)AnimationSet(組合漸變)

<set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/decelerate_interpolator"  
    android:shareInterpolator="true" >  

    <scale  
        android:duration="2000"  
        android:fromXScale="0.2"  
        android:fromYScale="0.2"  
        android:pivotX="50%"  
        android:pivotY="50%"  
        android:toXScale="1.5"  
        android:toYScale="1.5" />  

    <rotate  
        android:duration="1000"  
        android:fromDegrees="0"  
        android:repeatCount="1"  
        android:repeatMode="reverse"  
        android:toDegrees="360" />  

    <translate  
        android:duration="2000"  
        android:fromXDelta="0"  
        android:fromYDelta="0"  
        android:toXDelta="320"  
        android:toYDelta="0" />  

    <alpha  
        android:duration="2000"  
        android:fromAlpha="1.0"  
        android:toAlpha="0.1" />  

</set>  

屬性解釋:

fillBefore/ fillAfter:true/false,表示動(dòng)畫的轉(zhuǎn)化在動(dòng)畫結(jié)束后是否應(yīng)用;
fillBefore是指動(dòng)畫結(jié)束時(shí)畫面停留在第一幀,fillAfter是指動(dòng)畫結(jié)束是畫面停留在最后一幀。
這2個(gè)參數(shù)不能在 alpha,scale,translate,rotate節(jié)點(diǎn)中設(shè)置,在其中設(shè)置不起作用;
必須1)在動(dòng)畫xml文件的set節(jié)點(diǎn)中設(shè)置,或者在Activity中設(shè)置setFillAfter()/setFillBefore()。

pivot:這個(gè)屬性主要是在translate 和 scale 動(dòng)畫中,這兩種動(dòng)畫都牽扯到view 的“物理位置“發(fā)生變化,所以需要一個(gè)參考點(diǎn)。
pivotX和pivotY就共同決定了這個(gè)點(diǎn);它的值可以是float或者是百分比數(shù)值。
pivotX取值如下,pivotY取值同理。參考點(diǎn)都50%、50%即View自己的中心點(diǎn)。

pivotX取值 含義
10 參考點(diǎn)距離動(dòng)畫所在view自身左邊緣10像素
10% 參考點(diǎn)距離動(dòng)畫所在view自身左邊緣 的距離是整個(gè)view寬度的10%
10%p 參考點(diǎn)距離動(dòng)畫所在view父控件左邊緣的距離是整個(gè)view寬度的10%

這5個(gè)標(biāo)簽有一個(gè)共有的屬性android:interpolator,Interpolator用來控制動(dòng)畫的變化速度。
而Android中已經(jīng)提供了五個(gè)可供選擇的實(shí)現(xiàn)類:

  • LinearInterpolator:動(dòng)畫以均勻的速度改變
  • AccelerateInterpolator:在動(dòng)畫開始的地方改變速度較慢,然后開始加速
  • AccelerateDeceerateInterpolator:在動(dòng)畫開始、結(jié)束的地方改變速度較慢,中間時(shí)加速
  • CycleInterpolator:動(dòng)畫循環(huán)播放特定次數(shù),變化速度按正弦曲線改變:Math.sin(2 * mCycles * Math.PI * input)
  • DecelerateInterpolator:在動(dòng)畫開始的地方改變速度較快,然后開始減速
  • AnticipateInterpolator:反向,先向相反方向改變一段再加速播放
  • AnticipateOvershootInterpolator:開始的時(shí)候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator: 跳躍,快到目的值時(shí)值會(huì)跳躍,如目的值100,后面的值可能依次為85,77,70,80,90,100
  • OvershottInterpolator:回彈,最后超出目的值然后緩慢改變到目的值

6)實(shí)例

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_alpha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="透明度漸變" />

    <Button
        android:id="@+id/btn_scale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="縮放漸變" />

    <Button
        android:id="@+id/btn_tran"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="位移漸變" />

    <Button
        android:id="@+id/btn_rotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="旋轉(zhuǎn)漸變" />

    <Button
        android:id="@+id/btn_set"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="組合漸變" />

    <ImageView
        android:id="@+id/img_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="48dp"
        android:src="@mipmap/img_face" />

</LinearLayout>

MainActivity.Java
調(diào)用AnimationUtils.loadAnimation()加載動(dòng)畫,View控件調(diào)用startAnimation開啟動(dòng)畫。

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private Button btn_alpha;
    private Button btn_scale;
    private Button btn_tran;
    private Button btn_rotate;
    private Button btn_set;
    private ImageView img_show;
    private Animation animation = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
    }

    private void bindViews() {
        btn_alpha = (Button) findViewById(R.id.btn_alpha);
        btn_scale = (Button) findViewById(R.id.btn_scale);
        btn_tran = (Button) findViewById(R.id.btn_tran);
        btn_rotate = (Button) findViewById(R.id.btn_rotate);
        btn_set = (Button) findViewById(R.id.btn_set);
        img_show = (ImageView) findViewById(R.id.img_show);

        btn_alpha.setOnClickListener(this);
        btn_scale.setOnClickListener(this);
        btn_tran.setOnClickListener(this);
        btn_rotate.setOnClickListener(this);
        btn_set.setOnClickListener(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_alpha:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_alpha);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_scale:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_scale);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_tran:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_translate);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_rotate:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_rotate);
                img_show.startAnimation(animation);
                break;
            case R.id.btn_set:
                animation = AnimationUtils.loadAnimation(this,
                        R.anim.anim_set);
                img_show.startAnimation(animation);
                break;
        }
    }
}

動(dòng)畫狀態(tài)的監(jiān)聽

調(diào)用動(dòng)畫對(duì)象的: setAnimationListener(new AnimationListener())方法,重寫下面的三個(gè)方法:

onAnimationStart():動(dòng)畫開始;
onAnimtaionRepeat():動(dòng)畫重復(fù);
onAnimationEnd():動(dòng)畫結(jié)束;

為View動(dòng)態(tài)設(shè)置動(dòng)畫效果

靜態(tài)加載:先調(diào)用AnimationUtils.loadAnimation(),然后View控件用startAnimation()開始動(dòng)畫;
動(dòng)態(tài)加載:即直接創(chuàng)建一個(gè)動(dòng)畫對(duì)象,用Java代碼完成設(shè)置,再調(diào)用startAnimation開啟動(dòng)畫。


屬性動(dòng)畫

定義:通過不斷地對(duì)屬性值進(jìn)行操作的機(jī)制,并將值賦值到指定對(duì)象的指定屬性上,從而實(shí)現(xiàn)動(dòng)畫效果。

使用屬性動(dòng)畫原因:

  • 補(bǔ)間動(dòng)畫只是改變了View的顯示效果而已,而不會(huì)真正去改變View的屬性,即只是單純的動(dòng)畫效果
    • 視覺上,補(bǔ)間動(dòng)畫的set節(jié)點(diǎn)中設(shè)置android:fillAfter="true",可以實(shí)現(xiàn)動(dòng)畫結(jié)束后保留在最后一幀,即應(yīng)用動(dòng)畫效果的改變;
    • 實(shí)際上,補(bǔ)間動(dòng)畫只是將view繪制到指定位置,形成動(dòng)畫,實(shí)際上的控件依然停留在原有位置;
  • 補(bǔ)間動(dòng)畫只能夠?qū)崿F(xiàn)移動(dòng)、縮放、旋轉(zhuǎn)和淡入淡出這四種動(dòng)畫操作,即無擴(kuò)展性,無法實(shí)現(xiàn)其他效果
  • 補(bǔ)間動(dòng)畫是只能夠作用在View上的動(dòng)畫,對(duì)于自定義View無法添加補(bǔ)間動(dòng)畫

1)ValueAnimator

ValueAnimator負(fù)責(zé)進(jìn)行對(duì)不斷變化的屬性值的計(jì)算,以實(shí)現(xiàn)初始值和結(jié)束值之間的動(dòng)畫過渡。
將初始值和結(jié)束值提供給ValueAnimator,并且告訴它動(dòng)畫所需運(yùn)行的時(shí)長,ValueAnimator就會(huì)自動(dòng)完成從初始值平滑地過渡到結(jié)束值這樣的效果。除此之外,ValueAnimator還負(fù)責(zé)管理動(dòng)畫的播放次數(shù)、播放模式、以及對(duì)動(dòng)畫設(shè)置監(jiān)聽器等。

使用流程:

  1. 調(diào)用ValueAnimator的ofInt(),ofFloat()或ofObject()靜態(tài)方法創(chuàng)建ValueAnimator實(shí)例;方法參數(shù)為多個(gè)對(duì)應(yīng)類型的值。
  2. 調(diào)用實(shí)例的setXxx方法設(shè)置動(dòng)畫持續(xù)時(shí)間,插值方式,重復(fù)次數(shù)等;
  3. 調(diào)用實(shí)例的addUpdateListener添加AnimatorUpdateListener監(jiān)聽器,在該監(jiān)聽器中可以獲得ValueAnimator計(jì)算出來的值,值應(yīng)用到指定對(duì)象上;
  4. 調(diào)用實(shí)例的start()方法開啟動(dòng)畫。

使用范例:

//旋轉(zhuǎn)的同時(shí)透明度變化
    private void raAnimator(){
        ValueAnimator rValue = ValueAnimator.ofInt(0, 360);
        rValue.setDuration(1000L);
        rValue.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int rotateValue = (Integer) animation.getAnimatedValue();
                img_babi.setRotation(rotateValue);
                float fractionValue = animation.getAnimatedFraction();
                img_babi.setAlpha(fractionValue);
            }
        });
        rValue.setInterpolator(new DecelerateInterpolator());
        rValue.start();
    }

2)ObjectAnimator

ObjectAnimator為ValueAnimator的子類,使用方法類似于ValueAnimator。
ObjectAnimator能對(duì)任意對(duì)象的任意屬性進(jìn)行動(dòng)畫操作的,使用范圍更廣。

ObjectAnimator使用更為簡單,不需要自己寫回調(diào)。

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
//ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); 
//ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);  
//ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f);  
animator.setDuration(5000);  
animator.start(); 

對(duì)于ObjectAnimator.ofFloat()方法,第二個(gè)參數(shù)即對(duì)應(yīng)的ObjectAnimator指定要改變的對(duì)象的值,可以為任意的值。
常用的參數(shù)項(xiàng)有:alpha、rotation、translationX和scaleY等等。

ObjectAnimator內(nèi)部的工作機(jī)制并不是直接對(duì)傳入的屬性名進(jìn)行操作的,而是會(huì)去尋找這個(gè)屬性名對(duì)應(yīng)的get和set方法,因此alpha屬性所對(duì)應(yīng)的get和set方法應(yīng)該就是getAlpha()與setAlpha(),這兩個(gè)方法由View對(duì)象提供,同理,其他屬性一樣。即只要繼承自View的類都可以對(duì)其進(jìn)行這些動(dòng)畫操作。

3)AnimatorSet

實(shí)現(xiàn)組合動(dòng)畫功能
實(shí)現(xiàn)組合動(dòng)畫功能主要需要借助AnimatorSet這個(gè)類,這個(gè)類提供了一個(gè)play()方法,如果我們向這個(gè)方法中傳入一個(gè)Animator對(duì)象(ValueAnimator或ObjectAnimator)將會(huì)返回一個(gè)AnimatorSet.Builder的實(shí)例。

AnimatorSet.Builder中包括以下四個(gè)方法:

  • after(Animator anim) 將現(xiàn)有動(dòng)畫插入到傳入的動(dòng)畫之后執(zhí)行
  • after(long delay) 將現(xiàn)有動(dòng)畫延遲指定毫秒后執(zhí)行
  • before(Animator anim) 將現(xiàn)有動(dòng)畫插入到傳入的動(dòng)畫之前執(zhí)行
  • with(Animator anim) 將現(xiàn)有動(dòng)畫和傳入的動(dòng)畫同時(shí)執(zhí)行
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);  
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f); 
AnimatorSet animSet = new AnimatorSet();  
animSet.play(rotate).with(fadeInOut).after(moveIn);  
animSet.setDuration(5000);  
animSet.start();

4)AnimatorListener

Animator類中提供了addListener()方法,這個(gè)方法接收一個(gè)AnimatorListener。
實(shí)現(xiàn)AnimatorListener監(jiān)聽動(dòng)畫的各種事件。

AnimatorListener中重寫下面全部的四個(gè)回調(diào)方法:

anim.addListener(new AnimatorListener() {  
    //  動(dòng)畫開始
    public void onAnimationStart(Animator animation) {
    }  
  
    //  動(dòng)畫重復(fù)執(zhí)行  
    public void onAnimationRepeat(Animator animation) {  
    }  
  
    //  動(dòng)畫結(jié)束
    public void onAnimationEnd(Animator animation) {  
    }  
  
    //  動(dòng)畫取消
    public void onAnimationCancel(Animator animation) {  
    }  
});

當(dāng)只想重寫其中部分方法時(shí),接收的是AnimatorListenerAdapter,解決接口繁瑣的問題。

anim.addListener(new AnimatorListenerAdapter() {  
    @Override  
    public void onAnimationEnd(Animator animation) {  
    }  
});  

5)使用xml定義動(dòng)畫

使用標(biāo)簽定義動(dòng)畫,Activity中調(diào)用AnimatorInflater的loadAnimator來將XML動(dòng)畫文件加載進(jìn)來,然后再調(diào)用setTarget()方法將這個(gè)動(dòng)畫設(shè)置到某一個(gè)對(duì)象上面,最后再調(diào)用start()方法啟動(dòng)動(dòng)畫。
但是xml定義動(dòng)畫效果容易失效!建議使用Java代碼方式動(dòng)態(tài)加載動(dòng)畫

在res目錄下新建animator文件夾,右鍵new-Animation Resource file,新建文件的根目錄都是setXML中,在其子節(jié)點(diǎn)中添加代碼。

  • animator :對(duì)應(yīng)代碼中的ValueAnimator
  • objectAnimator :對(duì)應(yīng)代碼中的ObjectAnimator
  • set :對(duì)應(yīng)代碼中的AnimatorSet

定義動(dòng)畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together">
    <objectAnimator
        android:propertyName="string"
        android:duration="1000"
        android:valueFrom="@android:color/white"
        android:valueTo="@android:color/holo_green_dark"
        android:startOffset="500"
        android:repeatCount="1"
        android:repeatMode="restart"
        android:valueType="intType"/>
    <animator
        android:duration="1000"
        android:valueFrom="@android:color/white"
        android:valueTo="@android:color/holo_green_dark"
        android:startOffset="10"
        android:repeatCount="1"
        android:repeatMode="restart"
        android:valueType="intType"/>
</set>

使用動(dòng)畫

    Animator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file);  
    animator.setTarget(view);  
    animator.start();  

ValueAnimator、ObjectAnimator高級(jí)用法:
http://blog.csdn.net/guolin_blog/article/details/43816093
http://blog.csdn.net/guolin_blog/article/details/44171115


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

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