android屬性動(dòng)畫(huà)

屬性動(dòng)畫(huà)中最基礎(chǔ)的 ObjectAnimator

ObjectAnimator 是屬性動(dòng)畫(huà)中最重要的實(shí)行類(lèi),創(chuàng)建一個(gè)ObjectAnimator只需要通過(guò)他的靜態(tài)工廠方類(lèi)直接返回一個(gè)ObjectAnimator對(duì)象余爆。參數(shù)包括一個(gè)對(duì)象和對(duì)象的屬性名字寇窑,但這個(gè)屬性必須有getset函數(shù)却桶,內(nèi)部會(huì)通過(guò)反射機(jī)制來(lái)調(diào)用set函數(shù)修改對(duì)象屬性值,也可以調(diào)用setInterpolator設(shè)置對(duì)應(yīng)的差值器。

屬性動(dòng)畫(huà)操作的是屬性阶女,所以被操作的view可以響應(yīng)事件颊糜。

例子:實(shí)現(xiàn)平移動(dòng)畫(huà)

ObjectAnimator animator = ObjectAnimator.ofFloat(
                view,
                "translationX",
                300
        );
animator.setDuration(300);
animator.start();
  • 第一個(gè)參數(shù)是要操縱的View
  • 第二個(gè)參數(shù)是要操作的屬性
  • 第三個(gè)是一個(gè)可變數(shù)組參數(shù),需要穿進(jìn)去該屬性變化的一個(gè)取值過(guò)程秃踩,這里就是變化到300
  • 下面是給動(dòng)畫(huà)設(shè)置時(shí)長(zhǎng)衬鱼,差值器等屬性

注意到ofFloat方法,這是源碼中的注釋

/**
 * Constructs and returns an ObjectAnimator that animates between float values. A single
 * value implies that that value is the one being animated to. Two values imply starting
 * and ending values. More than two values imply a starting value, values to animate through
 * along the way, and an ending value (these values will be distributed evenly across
 * the duration of the animation).
 *
 * @param target The object whose property is to be animated. This object should
 * have a public method on it called <code>setName()</code>, where <code>name</code> is
 * the value of the <code>propertyName</code> parameter.
 * @param propertyName The name of the property being animated.
 * @param values A set of values that the animation will animate between over time.
 * @return An ObjectAnimator object that is set up to animate between the given values.
 */

大概意思是:

/**
 * 構(gòu)造并返回一個(gè)浮點(diǎn)值之間的動(dòng)畫(huà)ObjectAnimator憔杨。單
 * 值意味著該值被動(dòng)畫(huà)的之一鸟赫。兩個(gè)值意味著啟動(dòng)
 * 和結(jié)束值。多于兩個(gè)值意味著一個(gè)起始值芍秆,值動(dòng)畫(huà)通過(guò)
 * 一路走來(lái)惯疙,和結(jié)束值(這些值將均勻分布在整個(gè)
 * 動(dòng)畫(huà)的持續(xù)時(shí)間)。
 *
 * @參數(shù)target其屬性是動(dòng)畫(huà)的對(duì)象妖啥。這個(gè)對(duì)象應(yīng)該
 * 有它的公共方法叫做<代碼>的setName()</代碼>霉颠,其中<代碼>名稱(chēng)</ code>的是
 * 在<code>的值propertyname</ code>的參數(shù)。
 * @參數(shù)PROPERTYNAME被動(dòng)畫(huà)的屬性的名稱(chēng)荆虱。
 * @參數(shù)值一組動(dòng)畫(huà)將隨著時(shí)間的推移之間的動(dòng)畫(huà)值蒿偎。
 * 返回:已設(shè)置給定的值之間設(shè)置動(dòng)畫(huà)的ObjectAnimator對(duì)象。
 */

在使用ObjectAnimator的時(shí)候要注意的就是屬性必須有getset方法怀读,否則ObjectAnimator就無(wú)法生效诉位。下面是常用的可以直接使用屬性動(dòng)畫(huà)的屬性值:

  • translationXtranslationY:這兩個(gè)屬性作為一種增量來(lái)控制著View對(duì)象從它布局容器左上角坐標(biāo)偏移的位置。
  • rotation,rotationX,rotationY:這三個(gè)屬性控制View對(duì)象圍繞支點(diǎn)進(jìn)行2D和3D旋轉(zhuǎn)菜枷。
  • scaleX,scaleY:這兩個(gè)屬性控制View對(duì)象圍繞它的支點(diǎn)進(jìn)行2D縮放苍糠。
  • pivotX,pivotY:這兩個(gè)屬性控制著View對(duì)象的支點(diǎn)位置,圍繞這個(gè)支點(diǎn)進(jìn)行旋轉(zhuǎn)和縮放變換處理啤誊。默認(rèn)情況下岳瞭,支點(diǎn)是View對(duì)象的中心點(diǎn)。
  • xy:這是兩個(gè)簡(jiǎn)單實(shí)用的屬性蚊锹,它描述了View對(duì)象在它容器中的最終位置瞳筏,它是最初左上角坐標(biāo)和translationX、translationY值的累計(jì)和牡昆。
  • alpha:它表示View對(duì)象的alpha透明度姚炕。默認(rèn)是1(不透明),0代表完全透明(不可見(jiàn))

如果一個(gè)屬性沒(méi)有有getset方法丢烘,有兩種解決方法柱宦。

  1. 通過(guò)自定義一個(gè)屬性類(lèi)或包裝類(lèi)來(lái)間接給這個(gè)屬性添加get、set方法播瞳。
  2. 通過(guò)ValueAnimator實(shí)現(xiàn)

第一種捷沸,通過(guò)自定義一個(gè)屬性類(lèi)或包裝類(lèi)來(lái)間接給這個(gè)屬性添加get、set方法:

WrapperView wrapper = new WrapperView(view);
ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();


private static class WrapperView {
    private View mTarget;

    public WrapperView(View mTarget) {
        this.mTarget = mTarget;
    }

    public int getWidth() {
        return mTarget.getLayoutParams().width;
    }

    public void setWidth(int width) {
        mTarget.getLayoutParams().width = width;
        mTarget.requestLayout();
    }
}

PropertyValuesHolder

如果針對(duì)同一個(gè)對(duì)象的多個(gè)屬性狐史,要同時(shí)作用多種動(dòng)畫(huà)痒给,可以使用PropertyValuesHolder來(lái)實(shí)現(xiàn)说墨,比如在平移中,同時(shí)改變X苍柏、Y軸的縮放尼斧,可以這樣實(shí)現(xiàn):

PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", 300f);
PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3).setDuration(1000).start();

ValueAnimator

ValueAnimator本身不提供任何動(dòng)畫(huà)效果,它更像一個(gè)數(shù)值發(fā)生器试吁,用來(lái)產(chǎn)生具有一定規(guī)律的數(shù)字棺棵。從而讓調(diào)用者控制動(dòng)畫(huà)的實(shí)現(xiàn)過(guò)程,ValueAnimator的一般使用方法如下:

ValueAnimator animator = ValueAnimator.ofFloat(0, 100);
animator.setTarget(view);
animator.setDuration(5000).start();
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Float value = (Float) animation.getAnimatedValue();
        //TODO use the value
        Log.i("MainActivity", "value = " + value);
    }
});

其中AnimatorUpdateListener監(jiān)聽(tīng)數(shù)值的變換熄捍,從而完成動(dòng)畫(huà)的變換烛恤,這個(gè)例子中,value輸出的是從0到100

動(dòng)畫(huà)事件監(jiān)聽(tīng)

一個(gè)完整的動(dòng)畫(huà)監(jiān)聽(tīng)包括四個(gè)過(guò)程:

ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f);
anim.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animation) {
        
    }

    @Override
    public void onAnimationEnd(Animator animation) {

    }

    @Override
    public void onAnimationCancel(Animator animation) {

    }

    @Override
    public void onAnimationRepeat(Animator animation) {

    }
});

但是大部分時(shí)候余耽,我們只關(guān)心onAnimationEnd事件缚柏,所以還可以這樣通過(guò)AnimatorListenerAdapter選擇想要的事件進(jìn)行監(jiān)聽(tīng):

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

AnimatorSet

對(duì)于一個(gè)屬性同時(shí)作用多個(gè)屬性動(dòng)畫(huà)效果,除了使用PropertyValuesHolder外碟贾,還可以使用AnimatorSet,而且AnimatorSet還可以實(shí)現(xiàn)更為精確的順序控制币喧。

ObjectAnimator animator1 = ObjectAnimator.ofFloat(view, "translationX", 300f);
ObjectAnimator animator2 = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0, 1f);
ObjectAnimator animator3 = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0, 1f);
AnimatorSet set = new AnimatorSet();
set.setDuration(1000);
set.playTogether(animator1, animator2, animator3);
set.start();

在屬性動(dòng)畫(huà)中,AnimatorSet通過(guò)playTogether();playSequentially();set.play().with();set.play().before();set.play().after();這些方法來(lái)控制多個(gè)動(dòng)畫(huà)的協(xié)同工作方式袱耽,從而做到對(duì)動(dòng)畫(huà)播放順序的精確控制杀餐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市朱巨,隨后出現(xiàn)的幾起案子史翘,更是在濱河造成了極大的恐慌,老刑警劉巖冀续,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件琼讽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡沥阳,警方通過(guò)查閱死者的電腦和手機(jī)跨琳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)自点,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)桐罕,“玉大人,你說(shuō)我怎么就攤上這事桂敛」ε冢” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵术唬,是天一觀的道長(zhǎng)薪伏。 經(jīng)常有香客問(wèn)我,道長(zhǎng)粗仓,這世上最難降的妖魔是什么嫁怀? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任设捐,我火速辦了婚禮,結(jié)果婚禮上塘淑,老公的妹妹穿的比我還像新娘萝招。我一直安慰自己,他們只是感情好存捺,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布槐沼。 她就那樣靜靜地躺著,像睡著了一般捌治。 火紅的嫁衣襯著肌膚如雪岗钩。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 50,096評(píng)論 1 291
  • 那天肖油,我揣著相機(jī)與錄音兼吓,去河邊找鬼。 笑死构韵,一個(gè)胖子當(dāng)著我的面吹牛周蹭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播疲恢,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼凶朗,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了显拳?” 一聲冷哼從身側(cè)響起棚愤,我...
    開(kāi)封第一講書(shū)人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎杂数,沒(méi)想到半個(gè)月后宛畦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揍移,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年次和,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片那伐。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踏施,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罕邀,到底是詐尸還是另有隱情畅形,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布诉探,位于F島的核電站日熬,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肾胯。R本人自食惡果不足惜竖席,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一耘纱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧毕荐,春花似錦揣炕、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至虽填,卻和暖如春丁恭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斋日。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工牲览, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恶守。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓第献,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親兔港。 傳聞我的和親對(duì)象是個(gè)殘疾皇子庸毫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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