動畫 -- 屬性動畫 -- ValueAnimator

屬性動畫是 API 11 新加入的特性,和View動畫不同,它對作用對象進(jìn)行了擴(kuò)展,屬性動畫可以對任何對象做動畫而不僅僅是View,甚至還可以沒有對象。除了作用對象進(jìn)行了擴(kuò)展以外,屬性動畫的效果也得到了加強(qiáng)。

屬性動畫默認(rèn)時間間隔300ms,默認(rèn)幀率10ms/幀,其可達(dá)到的效果是:在一個時間間隔內(nèi)完成對象從一個屬性值到另一個屬性值的改變。因此,屬性動畫幾乎是無所不能的,只要對象有這個屬性,它都能實(shí)現(xiàn)動畫效果。但是屬性動畫從 API 11 才有,這就嚴(yán)重制約了屬性動畫的使用,可以采用開源動畫庫nineoldandroids來兼容以前的版本,nineoldandroids對屬性動畫做了兼容,在 API 11 以前的版本其內(nèi)部是通過代理View動畫來實(shí)現(xiàn)的,因此在Android低版本上,它的本質(zhì)還是View動畫,盡管使用方法看起來是屬性動畫。

屬性動畫有ValueAnimator、ObjectAnimator和AnimatorSet等概念。


屬性動畫 層次結(jié)構(gòu)

本小節(jié)學(xué)習(xí)ValueAnimator。

一、概念

ValueAnimator,標(biāo)簽:<animator>
對屬性值進(jìn)行動畫,不會對UI造成改變,不能直接實(shí)現(xiàn)動畫效果,需要對動畫進(jìn)行監(jiān)聽,在監(jiān)聽過程中將這個屬性值設(shè)置給對應(yīng)的屬性,對應(yīng)的屬性才會改變。

二、實(shí)現(xiàn)

1. XML實(shí)現(xiàn)

//res/animator/value_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="5000"
    android:valueFrom="0"
    android:valueTo="1"
    android:valueType="floatType"
    />

//布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/main_tv"
        android:layout_width="wrap_content"
        android:layout_height="100px"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:text="Hello Android!"
        android:background="@color/colorPrimary"/>
</RelativeLayout>

//代碼,MainActivity
private void valueAnimatorXML() {
    mValueAnimator = (ValueAnimator)AnimatorInflater.loadAnimator(this, R.animator.value_animator);
    mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float value = (Float) animation.getAnimatedValue();
            Log.d("MainActivity", "zwm, onAnimationUpdate value: " + value);
            mMain_tv.setAlpha(value);
        }
    });
    mValueAnimator.start();
}

private void stopAnimator() {
    mValueAnimator.cancel();
}

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

@Override
protected void onDestroy() {
    super.onDestroy();
    stopAnimator();
}

2. 代碼實(shí)現(xiàn)

//布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/main_tv"
        android:layout_width="wrap_content"
        android:layout_height="100px"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:text="Hello Android!"
        android:background="@color/colorPrimary"/>
</RelativeLayout>

//代碼,MainActivity
private void valueAnimatorCode() {
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float value = (Float) animation.getAnimatedValue();
            mMain_tv.setAlpha(value);
        }
    });
    valueAnimator.setDuration(5000);
    valueAnimator.start();
}

private void stopAnimator() {
    mValueAnimator.cancel();
}

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

@Override
protected void onDestroy() {
    super.onDestroy();
    stopAnimator();
}

在實(shí)際開發(fā)中建議采用代碼來實(shí)現(xiàn)屬性動畫,這是因為通過代碼來實(shí)現(xiàn)比較簡單。更重要的是,很多時候一個屬性的起始值是無法提前確定的,比如讓一個Button從屏幕左邊移動到屏幕右邊,由于我們無法提前知道屏幕的寬度,因此無法將屬性動畫定義在XML中,在這種情況下就必須通過代碼來動態(tài)地創(chuàng)建屬性動畫。

三、屬性

android:duration:
表示動畫的時長。
android:valueFrom:
表示屬性的起始值。
android:valueTo:
表示屬性的結(jié)束值。
android:startOffset:
表示動畫的延遲時間,當(dāng)動畫開始后,需要延遲多少毫秒才會真正播放此動畫。
android:repeatCount:
表示動畫的重復(fù)次數(shù)。默認(rèn)值為0,其中-1表示無限循環(huán)。
android:repeatMode:
表示動畫的重復(fù)模式。有"restart"和"reverse"兩個選項,分別表示連續(xù)重復(fù)和逆向重復(fù),連續(xù)重復(fù)就是每次都重新開始播放,逆向重復(fù)就是第一次播放完以后,第二次會倒著播放,第三次再重頭開始播放,第四次再倒著播放,如此重復(fù)。
android:valueType:
表示屬性的類型。有"intType"和"floatType"兩個選項,分別表示屬性的類型為整型和浮點(diǎn)型。

四、動畫過程監(jiān)聽

屬性動畫提供了監(jiān)聽器用于監(jiān)聽動畫的播放過程,主要有兩個接口:AnimatorUpdateListener和AnimatorListener。
AnimatorListener定義如下,它可以監(jiān)聽動畫的開始、結(jié)束、取消以及重復(fù)播放。

public static interface AnimatorListener {
    void onAnimationStart(Animator animation);
    void onAnimationEnd(Animator animation);
    void onAnimationCancel(Animator animation);
    void onAnimationRepeat(Animator animation);
}

AnimatorUpdateListener定義如下,它會監(jiān)聽整個動畫過程,動畫是由許多幀組成的,每播放一幀,onAnimationUpdate就會被調(diào)用一次。

public static interface AnimatorUpdateListener {
    void onAnimationUpdate(ValueAnimator animation);
}

實(shí)現(xiàn)如下:

private void valueAnimatorCode() {
    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);

    valueAnimator.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
            Log.d("MainActivity", "zwm, onAnimationStart");
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            Log.d("MainActivity", "zwm, onAnimationEnd");
        }

        @Override
        public void onAnimationCancel(Animator animation) {
            Log.d("MainActivity", "zwm, onAnimationCancel");
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
            Log.d("MainActivity", "zwm, onAnimationRepeat");
        }
    });

    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float value = (Float) animation.getAnimatedValue();
            Log.d("MainActivity", "zwm, onAnimationUpdate value: " + value);
            mMain_tv.setAlpha(value);
        }
    });

    valueAnimator.setDuration(5000);
    valueAnimator.start();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ObjectAnimator是最常用的屬性動畫,他能直接作用在對象上實(shí)現(xiàn)動畫。 概覽 先看一下屬性動畫的結(jié)構(gòu),Vi...
    喵了個嗚s閱讀 31,297評論 1 16
  • 1 背景 不能只分析源碼呀,分析的同時也要整理歸納基礎(chǔ)知識,剛好有人微博私信讓全面說說Android的動畫,所以今...
    未聞椛洺閱讀 2,850評論 0 10
  • 其實(shí)我一直想發(fā)條短信給你,或者打個電話。只是手機(jī)壞了,沒有了任何電話,也沒有認(rèn)識的人知道你,在網(wǎng)上倒是可以搜到你的...
    淚雨飛花閱讀 380評論 0 0
  • 下一站——南海紫竹林。 在普陀山乘坐的小巴都是和寺廟外墻一樣的顏色,車?yán)锖軟隹?,山路曲折,坐后面一不小心還得暈車嘞...
    黃勤息閱讀 906評論 0 1
  • Mr. Knightly looks a little bit surprised, curious, and i...
    Maia在簡書閱讀 270評論 0 0

友情鏈接更多精彩內(nèi)容