屬性動畫 Property Animation

——轉(zhuǎn)自 黑馬論壇 唐楊老師
屬性動畫(Property Animation)系統(tǒng)是一個健壯的動畫框架系統(tǒng)铺峭,它可以滿足你大部分動畫需求墓怀。不管動畫對象是否已經(jīng)繪制到屏幕上,你都可以在動畫執(zhí)行過程中改變它任意的屬性值卫键。一個屬性動畫會在一段特定長度的時間內(nèi)改變一個屬性(一個對象中的字段)的值傀履。你可以通過以下幾步定義一個動畫:指定你要執(zhí)行動畫的屬性,比如動畫對象(View)在屏幕上的位置莉炉,指定執(zhí)行時長钓账,指定你希望的屬性的變化值碴犬。

同類技術(shù)對比:

1. 補(bǔ)間動畫(Tween Animation)
  1. 漸變動畫支持四種類型:平移(Translate)、旋轉(zhuǎn)(Rotate)官扣、縮放(Scale)翅敌、不透明度(Alpha)。
  2. 只是顯示的位置變動惕蹄,View的實(shí)際位置未改變蚯涮,表現(xiàn)為View移動到其他地方,點(diǎn)擊事件仍在原處才能響應(yīng)卖陵。
  3. 組合使用步驟較復(fù)雜遭顶。
  4. View Animation 也是指此動畫。
2. 幀動畫(Frame Animation)
  1. 用于生成連續(xù)的Gif效果圖泪蔫。
  2. Drawable Animation也是指此動畫棒旗。
3. 屬性動畫(Property Animation)
  1. 支持對所有View能更新的屬性的動畫(需要屬性的setXxx()和getXxx())。
  2. 更改的是View實(shí)際的屬性撩荣,所以不會影響其在動畫執(zhí)行后所在位置的正常使用铣揉。
  3. Android3.0 (API11)及以后出現(xiàn)的功能,3.0之前的版本可使用github第三方開源庫nineoldandroids.jar進(jìn)行支持餐曹。

屬性動畫組成部分逛拱、相關(guān)類介紹:

  1. ObjectAnimator :對象動畫執(zhí)行類。
  2. ValueAnimator :值動畫執(zhí)行類台猴,常配合AnimatorUpdateListener使用朽合。
  3. PropertyValuesHolder : 屬性存儲器,為兩個執(zhí)行類提供更新多個屬性的功能饱狂。
  4. Keyframe :為 PropertyValuesHolder提供多個關(guān)鍵幀的操作值曹步。
  5. AnimatorSet :一組動畫的執(zhí)行集合類:設(shè)置執(zhí)行的先后順序,時間等休讳。
  6. AnimatorUpdateListener :動畫更新監(jiān)聽讲婚。
  7. AnimatorListener :動畫執(zhí)行監(jiān)聽,在動畫開始俊柔、重復(fù)磺樱、結(jié)束、取消時進(jìn)行回調(diào)婆咸。
  8. AnimatorInflater :加載屬性動畫的xml文件竹捉。
  9. TypeEvaluator :類型估值,用于設(shè)置復(fù)雜的動畫操作屬性的值尚骄。
  10. TimeInterpolator :時間插值块差,用于控制動畫執(zhí)行過程。

一、ObjectAnimator 對象動畫執(zhí)行類


介紹:

  1. 通過靜態(tài)方法 ofInt憨闰、ofFloat状蜗、ofObjectofPropertyValuesHolder 獲取類對象鹉动。
  2. 根據(jù)屬性值類型選擇靜態(tài)方法轧坎,如 view 的 setLeft(int left) 則選用 ofInt 方法, setY(float y) 則選用 ofFloat 方法。
  3. 同 ValueAnimator 一樣泽示,可以進(jìn)行串聯(lián)式使用缸血。
  4. 只能用于有 setXXX( )和 getXXX() 方法的屬性名稱!不然不會起作用械筛。

示例:

  1. 簡單示例:View 的橫向移動:
        // 通過靜態(tài)方法構(gòu)建一個ObjectAnimator對象
        // 設(shè)置作用對象捎泻、屬性名稱、數(shù)值集合
        ObjectAnimator.ofFloat(view, "translationX", 0.0F, 200.0F)
        // 設(shè)置執(zhí)行時間(1000ms)
                .setDuration(1000)
                // 開始動畫
                .start();
  1. 復(fù)合示例:View 彈性落下然后彈起埋哟,執(zhí)行一次:
        // 修改view的y屬性, 從當(dāng)前位置移動到300.0f
        ObjectAnimator yBouncer = ObjectAnimator.ofFloat(view, "y",
                view.getY(), 300.0f);
        yBouncer.setDuration(1500);
        // 設(shè)置插值器(用于調(diào)節(jié)動畫執(zhí)行過程的速度)
        yBouncer.setInterpolator(new BounceInterpolator());
        // 設(shè)置重復(fù)次數(shù)(缺省為0,表示不重復(fù)執(zhí)行)
        yBouncer.setRepeatCount(1);
        // 設(shè)置重復(fù)模式(RESTART或REVERSE),重復(fù)次數(shù)大于0或INFINITE生效
        yBouncer.setRepeatMode(ValueAnimator.REVERSE);
        // 設(shè)置動畫開始的延時時間(200ms)
        yBouncer.setStartDelay(200);
        // 開始動畫
        yBouncer.start();

二笆豁、ValueAnimator 值動畫執(zhí)行類


介紹:

  1. 構(gòu)造方法與 ObjectAnimator 類似。
  2. 與 ObjectAnimator 的區(qū)別在于 ValueAnimator 構(gòu)造函數(shù)的參數(shù)中不包含動畫“屬性”信息赤赊。
  3. 優(yōu)點(diǎn):結(jié)合動畫更新監(jiān)聽** onAnimationUpdate() **使用闯狱,可以在回調(diào)中不斷更新 View 的多個屬性,使用起來更加靈活抛计。

示例:

View 向右下角移動:

        // 通過靜態(tài)方法構(gòu)建一個ValueAnimator對象
        // 設(shè)置數(shù)值集合
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 200.0f);
        // 設(shè)置作用對象
        animator.setTarget(view);
        // 設(shè)置執(zhí)行時間(1000ms)
        animator.setDuration(1000);
        // 添加動畫更新監(jiān)聽
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                // 獲取當(dāng)前值
                Float mValue = (Float) animation.getAnimatedValue();
                // 設(shè)置橫向偏移量
                view.setTranslationX(mValue);
                // 設(shè)置縱向偏移量
                view.setTranslationY(mValue);
            }
        });
        // 開始動畫
        animator.start();
  • 可以理解為上面設(shè)置的 (0f, 200.0f)哄孤,0 到 200 的過程中,每次更新都會回調(diào) onAnimationUpdate()爷辱,每次回調(diào)都根據(jù)當(dāng)前值做一次動畫。



三朦肘、PropertyValuesHolder 屬性存儲器


介紹:

為 ValueAnimator 提供多個操作屬性及相應(yīng)的執(zhí)行參數(shù)饭弓。

示例:

同時修改 View 多個屬性的動畫:

        // 獲取view左邊位置
        int left = view.getLeft();
        // 獲取view右邊位置
        int right = view.getRight();
        // 將view左邊增加10像素
        PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", left,
                left + 10);
        // 將view右邊減少10像素
        PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right",
                right, right - 10);
        // 在X軸縮放從原始比例1f,縮小到最小0f,再放大到原始比例1f
        PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX",
                1f, 0f, 1f);
        // 在Y軸縮放從原始比例1f,縮小到最小0f,再放大到原始比例1f
        PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY",
                1f, 0f, 1f);
        // 將PropertyValuesHolder交付給ObjectAnimator進(jìn)行構(gòu)建
        ObjectAnimator customAnim = ObjectAnimator.ofPropertyValuesHolder(view,
                pvhLeft, pvhRight, pvhScaleX, pvhScaleY);
        // 設(shè)置執(zhí)行時間(1000ms)
        customAnim.setDuration(1000);
        // 開始動畫
        customAnim.start();

四、Keyframe 關(guān)鍵幀


介紹:

為 PropertyValuesHolder 提供關(guān)鍵幀的操作值集合媒抠。

示例:

以下示例表示該 PropertyValuesHolder 進(jìn)行的旋轉(zhuǎn)(rotation)動畫弟断,在執(zhí)行時間在 0%, 50%, 100% 時,其旋轉(zhuǎn)角度分別為 0°, 360°, 0°。動畫執(zhí)行過程中自動進(jìn)行補(bǔ)間趴生。表現(xiàn)為自旋 360° 后再轉(zhuǎn)回來:

        // 設(shè)置在動畫開始時,旋轉(zhuǎn)角度為0度
        Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
        // 設(shè)置在動畫執(zhí)行50%時,旋轉(zhuǎn)角度為360度
        Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
        // 設(shè)置在動畫結(jié)束時,旋轉(zhuǎn)角度為0度
        Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
        // 使用PropertyValuesHolder進(jìn)行屬性名稱和值集合的封裝
        PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe(
                "rotation", kf0, kf1, kf2);
        // 通過ObjectAnimator進(jìn)行執(zhí)行
        ObjectAnimator.ofPropertyValuesHolder(view, pvhRotation)
        // 設(shè)置執(zhí)行時間(1000ms)
                .setDuration(1000)
                // 開始動畫
                .start();

五阀趴、AnimatorSet 執(zhí)行集合類


介紹:

  1. 為多個屬性動畫提供播放順序控制(注意 **play,with,after,before **的用法)。
  2. AnimatorSet 類與 AnimationSet 類不能搞混苍匆,AnimatorSet 在 3.0 及以上版本中才有刘急。3.0 之前的版本可使用第三方開源庫 nineoldandroids.jar 進(jìn)行支持,功能使用完全一致浸踩。

示例:

以下示例動畫的播放順序?yàn)?/p>

  1. 播放 bounceAnim;
  2. 同時播放 squashAnim1, squashAnim2,stretchAnim1, stretchAnim2;
  3. 接著播放 bounceBackAnim;
  4. 最后播放 fadeAnim;
         AnimatorSet bouncer = new AnimatorSet();
         bouncer.play(bounceAnim).before(squashAnim1);
         bouncer.play(squashAnim1).with(squashAnim2);
         bouncer.play(squashAnim1).with(stretchAnim1);
         bouncer.play(squashAnim1).with(stretchAnim2);
         bouncer.play(bounceBackAnim).after(stretchAnim2);
         ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f,
         0f);
         fadeAnim.setDuration(250);
         AnimatorSet animatorSet = new AnimatorSet();
         animatorSet.play(bouncer).before(fadeAnim);
         animatorSet.start();

六叔汁、AnimatorListener 動畫執(zhí)行監(jiān)聽


介紹:

  1. 實(shí)現(xiàn) AnimatorListener 中的方法可在動畫執(zhí)行全程進(jìn)行其他任務(wù)的回調(diào)執(zhí)行。
  2. 也可以添加 AnimatorListener 的實(shí)現(xiàn)類 AnimatorListenerAdapter,僅重寫需要的監(jiān)聽即可据块。

示例:

將 view 透明度從當(dāng)前的 1.0f 更新為0.5f码邻,在動畫結(jié)束時移除該 View:

        ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
        anim.setDuration(1000);
        anim.addListener(new AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                // 動畫開始時調(diào)用
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
                // 動畫重復(fù)時調(diào)用
            }
            @Override
            public void onAnimationEnd(Animator animation) {
                // 動畫結(jié)束時調(diào)用
                ViewGroup parent = (ViewGroup) view.getParent();
                if (parent != null)
                    parent.removeView(view);
            }
            @Override
            public void onAnimationCancel(Animator animation) {
                // 動畫取消時調(diào)用
            }
        });
        anim.start();

七、AnimatorInflater 動畫加載器


介紹:

  1. 屬性動畫可以通過 xml 文件的形式加載另假。
  2. set 標(biāo)簽內(nèi)的 animator 也可單獨(dú)使用像屋。
  3. XML語法如下:
<set android:ordering=["together" | "sequentially"]>
          <objectAnimator
              android:propertyName="string"
              android:duration="int"
              android:valueFrom="float| int | color"
              android:valueTo="float| int | color"
              android:startOffset="int"
              android:repeatCount="int"
              android:repeatMode=["repeat"| "reverse"]
              android:valueType=["intType"| "floatType"]/>
          <animator
              android:duration="int"
              android:valueFrom="float| int | color"
              android:valueTo="float| int | color"
              android:startOffset="int"
              android:repeatCount="int"
              android:repeatMode=["repeat"| "reverse"]
              android:valueType=["intType"| "floatType"]/>
          <set>
              ...
          </set>
</set>

示例:

 <?xml version="1.0" encoding="utf-8"?>
<set>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:valueTo="200"
        android:valueType="floatType"
        android:propertyName="x"
        android:repeatCount="1"
        android:repeatMode="reverse"/>
    <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:valueTo="400"
        android:valueType="floatType"
        android:propertyName="y"
        android:repeatCount="1"
        android:repeatMode="reverse"/>
</set>
        // 加載xml屬性動畫
        Animator anim = AnimatorInflater
                .loadAnimator(this, R.anim.animator_set);
        anim.setTarget(view);
        anim.start();

八、TypeEvaluator 類型估值


介紹:

  1. TypeEvaluator 可傳入?yún)?shù)值的類型(本例為 PointF)边篮。
  2. 重寫函數(shù) public T evaluate(floatfraction, T startValue, T endValue);實(shí)現(xiàn)不同需求值的計(jì)算己莺。
  3. 注意 fraction 的使用,fraction 是從開始到結(jié)束的分度值 0.0 -> 1.0苟耻。

九篇恒、TimeInterpolator 時間插值器


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市凶杖,隨后出現(xiàn)的幾起案子胁艰,更是在濱河造成了極大的恐慌,老刑警劉巖智蝠,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件腾么,死亡現(xiàn)場離奇詭異,居然都是意外死亡杈湾,警方通過查閱死者的電腦和手機(jī)解虱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來漆撞,“玉大人殴泰,你說我怎么就攤上這事「〔担” “怎么了悍汛?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長至会。 經(jīng)常有香客問我离咐,道長,這世上最難降的妖魔是什么奉件? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任宵蛀,我火速辦了婚禮,結(jié)果婚禮上县貌,老公的妹妹穿的比我還像新娘术陶。我一直安慰自己,他們只是感情好煤痕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布瞳别。 她就那樣靜靜地躺著征候,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祟敛。 梳的紋絲不亂的頭發(fā)上疤坝,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音馆铁,去河邊找鬼跑揉。 笑死,一個胖子當(dāng)著我的面吹牛埠巨,可吹牛的內(nèi)容都是我干的历谍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼辣垒,長吁一口氣:“原來是場噩夢啊……” “哼望侈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起勋桶,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤脱衙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后例驹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捐韩,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年鹃锈,在試婚紗的時候發(fā)現(xiàn)自己被綠了荤胁。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡屎债,死狀恐怖仅政,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情盆驹,我是刑警寧澤圆丹,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站召娜,受9級特大地震影響运褪,放射性物質(zhì)發(fā)生泄漏惊楼。R本人自食惡果不足惜玖瘸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望檀咙。 院中可真熱鬧雅倒,春花似錦、人聲如沸弧可。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至裁良,卻和暖如春凿将,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背价脾。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工牧抵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侨把。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓犀变,卻偏偏與公主長得像,于是被迫代替她去往敵國和親秋柄。 傳聞我的和親對象是個殘疾皇子获枝,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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