Android Property Animation

概述


  • 屬性動畫踩麦,顧名思義-動態(tài)改變對象的屬性佛猛,以此變化來產(chǎn)生某種效果制妄。 這里的對象可是任何對象祠锣,并不限定是View控件酷窥。

  • 屬性動畫是Android 3.0(API 11)增加的,為何增加伴网?有何意義蓬推?

    • 你一定還記得在view animation 中,交互不友好(比如view的位置改變了澡腾,但是點擊事件還在原來的位置)
    • view animation 能讓view動起來的效果有限沸伏,屬性動畫可是打著能改變?nèi)魏螌ο蟮娜魏螌傩猿鰣龅模@樣就可以實現(xiàn)復(fù)雜高級效果了动分。
  • 系統(tǒng)為我們提供了屬性動畫哪些用法毅糟?出了具體表現(xiàn)在這些類,也支持XML中定義使用澜公。

    • ObjectAnimator
    • PropertyHolder
    • ValueAnimator
    • AnimatorSet
    • Animator.AnimatorListener
    • ValueAnimator.AnimatorUpdateListener
  • 屬性動畫中也要用到view動畫中的差值器等API姆另,也獨有估值器

ObjectAnimator


ObjectAnimator繼承關(guān)系

在這個類中,通過調(diào)用ObjectAnimator的工廠方法坟乾,傳入對應(yīng)的參數(shù)即可迹辐,舉個簡單的用法來看具體怎么使用

屬性動畫1.gif

這樣的效果用屬性動畫也是非常容易實現(xiàn)的

 ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageview, "translationX", 0f, imageview.getWidth());
 // 指定一個時間差值器(TimeInpolator),ObjectAnimator默認的是LinearInpolator
 objectAnimator1.setInterpolator(new AccelerateDecelerateInterpolator());
 objectAnimator1.setDuration(1000);
 objectAnimator1.start();

關(guān)于ofFloat(Object target, String propertyName, float... values)
第一個參數(shù)是要操縱的對象,第二個是操縱對象的屬性名甚侣,第三個是一個可變數(shù)組參數(shù)右核,表示屬性的取值變化的過程

列舉view的一些常見可以直接用的屬性值
view偏移量: translationX 、translationY
view2D和3D旋轉(zhuǎn)角度: rotation渺绒、rotationX贺喝、rotationY
view的2D縮放比例: scaleX、 scaleY
view的旋轉(zhuǎn)和縮放的中心點宗兼,默認是view的中心點:pivotX躏鱼、pivotY
view的坐標: x 、y
view的透明度: alpha

值得注意的是ObjectAnimator

  • 操縱的屬性必須具有set<propertyName>(),因為ObjectAnimator在動態(tài)改變屬性的過程中殷绍,會去通過set方法來改變這個屬性染苛。如果操縱的屬性沒有set方法,官方給出三種建議:
    • 如果你有權(quán)限的話就去給這個屬性添加一個set方法
    • 可以通過自定義一個屬性類或者包裝類,來間接給這個屬性增加set方法
    • 使用ValueAnimator來代替
  • 對于這個可變參數(shù)茶行,values...如果僅僅設(shè)置了一個參數(shù)躯概,會被認為這個值是變化過程的結(jié)束值。此刻ObjectAnimator會自動去通過get<propertyName>()來獲得變化的起始值畔师,這時就要求操作的屬性必須具有g(shù)et方法

這里我們舉個例子娶靡,操作一個自定義的對象

 public class Person {
    private int age;

    public void setAge(int age) {
        this.age = age;
        Log.d("age", "set年齡" + age);
    }

    public int getAge() {
        Log.d("age", "get年齡" + age);
        return age;

    }
}

這個時候我們?nèi)赢嫷母淖兯?/p>

 ObjectAnimator objectAnimator;
 // 1.屬性動畫可以對任意一個對象的屬性動態(tài)改變
 objectAnimator = ObjectAnimator.ofInt(new Person(), "age",5,  8);
 objectAnimator.start();

觀察這個時候的log

log1

和我們預(yù)想的一樣,動態(tài)改變了這個年齡值看锉,哈哈

如果我們對可變參數(shù)只設(shè)置一個參數(shù)呢姿锭?

 ObjectAnimator objectAnimator;
// 1.屬性動畫可以對任意一個對象的屬性動態(tài)改變
objectAnimator = ObjectAnimator.ofInt(new Person(), "age", 4);
objectAnimator.start();

這個時候的log 顯示表明調(diào)用了get方法獲得初始值

log2

雖然上面這個改變屬性值沒有實際意義,但是很清晰的展示了屬性動畫的魅力和變化過程伯铣。

你對為什么一個數(shù)值打印那么多遍感到很奇怪呻此?
其實這就是屬性動畫中有估值器(Evaluator)這個概念,這里我給采用的是ofInt 對應(yīng)的其實是IntEvaluator腔寡,這是ObjectAnimator內(nèi)部會去判斷,可以去源碼中查看焚鲜。
同理如果ofFloat對應(yīng)的就是FloatEvaluator
當然你也可以ofObject傳入自己想要的估值器

那么這個時候你把Personage屬性改成float, 并且動畫采用ofFloat,結(jié)果你會發(fā)現(xiàn)會一步一步接近最后的值放前。

反復(fù)調(diào)用set方法恃泪,一步步接近終值

PropertyValuesHolder


如果同時改變多個屬性呢?

可以直接構(gòu)造多個ObjetAnimator 然后調(diào)用start. 因為他們是異步的犀斋,這些動畫會同時執(zhí)行

  objectAnimator1.setInterpolator(new AccelerateDecelerateInterpolator());
  objectAnimator1.setDuration(1000);
  ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageview, "translationY", 0f, imageview.getHeight());
  objectAnimator2.setInterpolator(new AccelerateDecelerateInterpolator());
  objectAnimator2.setDuration(1000);
  ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageview, "rotationX", 0f, 360);
  objectAnimator3.setInterpolator(new AccelerateDecelerateInterpolator());
  objectAnimator3.setDuration(2000);
  objectAnimator1.start();
  objectAnimator2.start();
  objectAnimator3.start();;

還可以使用PropertyValuesHolder贝乎,然后調(diào)用的ObjectAnimator.ofPropertyValuesHolder

PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX",0f,imageview.getWidth());
PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat("translationY",0f,imageview.getHeight());
PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat("rotationX",0f,360f);
ObjectAnimator.ofPropertyValuesHolder(imageview, p1,p2,p3).setDuration(2000).start();

在上面的例子中,那如果我想控制他們的播放順序呢叽粹?

AnimatorSet


同時X,Y平移后旋轉(zhuǎn)

這個效果是先同時x和y方向平移動畫览效,然后在執(zhí)行旋轉(zhuǎn)

    ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageview, "translationX", 0f, imageview.getWidth());
    ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageview, "translationY", 0f, imageview.getHeight());
    ObjectAnimator objectAnimator3 = ObjectAnimator.ofFloat(imageview, "rotationX", 0f, 360);
    AnimatorSet set = new AnimatorSet();
    set.setDuration(2000);
    set.setInterpolator(new LinearInterpolator());
    //set.playTogether(objectAnimator1,objectAnimator2, objectAnimator3);
    //set.playSequentially(objectAnimator1,objectAnimator2, objectAnimator3);
    set.play(objectAnimator1).with(objectAnimator2).before(objectAnimator3); objectAnimator3);
    set.start();

可以將注釋部分觀察效果。AnimatorSet需要說明幾點:

  • playSequentially是單獨順序播放
  • play配合with虫几、before锤灿、after來按照這些規(guī)則播放動畫
  • playTogether 動畫同時播放

ValueAnimator的使用


通過上面的那個類關(guān)系圖,ValueAnimatorObjectAnimator的父類辆脸,實際上ObjectAnimator是更加具體化了ValueAnimator但校,實現(xiàn)了一系列的既定效果,更加方便的使用啡氢。那么上文提到如果一個屬性沒有set方法可以用ValueAnimator來代替.

什么意思呢状囱?其實就是說ValueAnimator,它并不要求你非要指定什么屬性倘是,注重的是值的變化亭枷,然后可以監(jiān)聽這些值的變化過程,從而自己來根據(jù)這些值搀崭,產(chǎn)生你自己需要的效果叨粘。比如你要做一個計時器,這個時候你可以ofInt在監(jiān)聽里面去設(shè)置UI 顯示倒計時的數(shù)值即可。

這里看一下如何監(jiān)聽等常規(guī)思路:

ValueAnimator valueAnimator = ValueAnimator.ofInt(1,15);// ValueAnimator ,ofInt,ofFloat,ofObject
   
    // valueAnimator.setEvaluator(new IntEvaluator()); // 設(shè)置估值器
    valueAnimator.setEvaluator(new TypeEvaluator<Integer>() {
        @Override
        public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
            // 這里自定義了一個估值器升敲,就是在int估值器的基礎(chǔ)上加一個1
            int startInt = startValue;
            return (int)(startInt + fraction * (endValue - startInt)+1);
        }
    });
    valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
           Log.d("smart","變化的值:" +animation.getAnimatedValue());
        }
    });
    valueAnimator.setDuration(3000);
    valueAnimator.start();

估值器

  • 系統(tǒng)定義的估值器:

    • IntEvaluator 計算整型
    • FloatEvaluator 計算float型
    • ArgbEvaluator 計算顏色
    • TypeEvaluator 是一個接口答倡,自定義估值器需要實現(xiàn)它
  • 如何自定義一個估值器

      public interface TypeEvaluator<T> {
    
          public T evaluate(float fraction, T startValue, T endValue);
      }
    

    實現(xiàn)這個接口,確定泛型的返回值T驴党。

至此 瘪撇,屬性動畫的基本概念敘述完畢!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鼻弧,一起剝皮案震驚了整個濱河市设江,隨后出現(xiàn)的幾起案子锦茁,更是在濱河造成了極大的恐慌攘轩,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件码俩,死亡現(xiàn)場離奇詭異度帮,居然都是意外死亡,警方通過查閱死者的電腦和手機稿存,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門笨篷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人瓣履,你說我怎么就攤上這事率翅。” “怎么了袖迎?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵冕臭,是天一觀的道長。 經(jīng)常有香客問我燕锥,道長辜贵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任归形,我火速辦了婚禮托慨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘暇榴。我一直安慰自己厚棵,他們只是感情好,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布蔼紧。 她就那樣靜靜地躺著窟感,像睡著了一般。 火紅的嫁衣襯著肌膚如雪歉井。 梳的紋絲不亂的頭發(fā)上柿祈,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機與錄音,去河邊找鬼躏嚎。 笑死蜜自,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的卢佣。 我是一名探鬼主播重荠,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼虚茶!你這毒婦竟也來了戈鲁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嘹叫,失蹤者是張志新(化名)和其女友劉穎婆殿,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罩扇,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡婆芦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了喂饥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片消约。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖员帮,靈堂內(nèi)的尸體忽然破棺而出或粮,到底是詐尸還是另有隱情,我是刑警寧澤捞高,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布氯材,位于F島的核電站,受9級特大地震影響棠枉,放射性物質(zhì)發(fā)生泄漏浓体。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一辈讶、第九天 我趴在偏房一處隱蔽的房頂上張望命浴。 院中可真熱鬧,春花似錦贱除、人聲如沸生闲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽碍讯。三九已至,卻和暖如春扯躺,著一層夾襖步出監(jiān)牢的瞬間捉兴,已是汗流浹背蝎困。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留倍啥,地道東北人禾乘。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像虽缕,于是被迫代替她去往敵國和親始藕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

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