屬性動(dòng)畫【Property animation】

第二次看屬性動(dòng)畫烁落,結(jié)合兩本書的介紹和郭神的博客來總結(jié)一下熄云。

Android3.0之后的動(dòng)畫系統(tǒng)是 幀動(dòng)畫,屬性動(dòng)畫诉稍,補(bǔ)間動(dòng)畫三足鼎立的局面蝠嘉。
那么他們各自有各自的優(yōu)缺點(diǎn),但是屬性動(dòng)畫是相對(duì)先進(jìn)的技術(shù)杯巨,至少它能解決view移動(dòng)事件不移動(dòng)的情況,它還帶來了更多豐富的效果和更豐富的接口來開發(fā)提升的效率蚤告。

那其實(shí)屬性動(dòng)畫能帶來的不只有這些,具體的好處可以在文末的連接參考郭神的博客服爷,大神寫的更加詳細(xì)杜恰。(同時(shí)本篇里的部分代碼借鑒于郭神的代碼)

1.ValueAnimator

在說屬性動(dòng)畫效果之前必須先討論這個(gè)東西。
ValueAnimator的作用并不是產(chǎn)生動(dòng)畫效果仍源,而是以特定算法來計(jì)算屬性值心褐,通過得到屬性值,Animator就可以對(duì)Object進(jìn)行一系列的動(dòng)畫笼踩,除此之外逗爹,ValueAnimator對(duì)于動(dòng)畫管理,監(jiān)聽器等地方也有所作用嚎于。

        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,100);
        valueAnimator.setTarget(textView);
        valueAnimator.setDuration(1000).start();
        valueAnimator.addUpdateListener(new 
        ValueAnimator.AnimatorUpdateListener() {
             @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                Float f = (Float) animation.getAnimatedValue();
               //Log打印f
            }
        });

我們需要搞到一個(gè)ValueAnimator對(duì)象掘而,那么其實(shí)是通過靜態(tài)工廠類返回對(duì)象挟冠,比如說我們調(diào)用的ofFloat方法,這里傳入一個(gè)可變參數(shù)镣屹,比如說我們給的(0,100)圃郊,

    //Android源碼
    public static ValueAnimator ofFloat(float... values) {
        ValueAnimator anim = new ValueAnimator();
        anim.setFloatValues(values);
        return anim;
    }

當(dāng)我們start這個(gè)動(dòng)畫之后,并給其添加一個(gè)動(dòng)畫的更新監(jiān)聽器女蜈,在終端打印下float的值持舆,你可以看到在1000ms的時(shí)間內(nèi),從0-100的特定規(guī)律變化

如果你想實(shí)現(xiàn)其他形式的變化可以如下:

 //0->5->3->10的跳躍性變化
ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f);  
//整數(shù)型變化
ValueAnimator anim = ValueAnimator.ofInt(0, 100); 

當(dāng)然作為動(dòng)畫數(shù)值生成類也是有setRepeat 伪窖, setRepeatMode之類的方法逸寓,主要是對(duì)數(shù)據(jù)進(jìn)行一些花樣的處理(同時(shí)也是滿足不同的動(dòng)畫效果,這些也是在補(bǔ)間動(dòng)畫上有的)

2.ObjectAnimator

到這里才進(jìn)入了我們真正的效果階段覆山,我們真實(shí)能看到效果的竹伸,展現(xiàn)到屏幕上的是ObjectAnimator,那前面說過簇宽,其實(shí)ObjectAnimator是基于ValueAnimator的數(shù)值變化來完成的勋篓,也可以說是ValueAnimator在后面默默地工作,ObjectAnimator才能展示出效果魏割。

同樣的ObjectAnimator的用法也是跟ValueAnimator差不多的譬嚣,通過靜態(tài)工廠返回對(duì)象,通過ofFloat來設(shè)置參數(shù)钞它,最后設(shè)置區(qū)間啟動(dòng)動(dòng)畫拜银。

比如下面的textview的透明度從不透明到全透明到不透明。

ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  
animator.setDuration(5000);  
animator.start();  

ofFloat源碼如下

  public static ObjectAnimator ofFloat(Object target, String propertyName, float... values) {
        ObjectAnimator anim = new ObjectAnimator(target, propertyName);
        anim.setFloatValues(values);
        return anim;
    }
參數(shù)1:Object目標(biāo)遭垛,也就是我們要實(shí)現(xiàn)動(dòng)畫的東西尼桶,不僅限于view
參數(shù)2:propertyName,屬性名稱锯仪,也就是我們要實(shí)現(xiàn)什么動(dòng)畫
參數(shù)3:可變參數(shù)泵督,主要是實(shí)現(xiàn)的動(dòng)畫的動(dòng)畫參數(shù)

這樣的話一個(gè)簡單的屬性動(dòng)畫就實(shí)現(xiàn)了。
同樣其他動(dòng)畫效果

//旋轉(zhuǎn)360°
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);  
animator.setDuration(5000);  
animator.start();  
//當(dāng)前位置平移-500(左移),然后移動(dòng)回來
float curTranslationX = textview.getTranslationX();  
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -500f, curTranslationX);  
animator.setDuration(5000);  
animator.start()

那么更多的效果也是可以用類似的方法來實(shí)現(xiàn)的庶喜。
具體的有以下幾種:

translationX & translationY :X與Y軸的平移效果
rotationX & rotationY & rotation:圍繞view本身的旋轉(zhuǎn)效果
PrivotX & PrivotY:圍繞著View中心點(diǎn)(默認(rèn))旋轉(zhuǎn)縮放的效果
scaleX & scaleY:中心點(diǎn)縮放的動(dòng)畫
alpha:透明度動(dòng)畫

但是我們?yōu)槭裁茨苡眠@些動(dòng)畫呢幌蚊,還記得在之前說過屬性動(dòng)畫不僅是用于view的,而是可以用于任何地方溃卡,那么這就說明屬性動(dòng)畫設(shè)計(jì)的時(shí)候沒有view限制,我們可以給第二個(gè)參數(shù)傳任何的值進(jìn)去蜒简,但是前提是對(duì)象有g(shù)et/set方法瘸羡,什么意思呢,拿textview舉例搓茬,我們?cè)趖extview的源碼中可以找到setAlpha()方法如下:

public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
        ensureTransformationInfo();
        if (mTransformationInfo.mAlpha != alpha) {
            // Report visibility changes, which can affect children, to accessibility
            if ((alpha == 0) ^ (mTransformationInfo.mAlpha == 0)) {
                notifySubtreeAccessibilityStateChangedIfNeeded();
            }
            mTransformationInfo.mAlpha = alpha;
            if (onSetAlpha((int) (alpha * 255))) {
                mPrivateFlags |= PFLAG_ALPHA_SET;
                // subclass is handling alpha - don't optimize rendering cache invalidation
                invalidateParentCaches();
                invalidate(true);
            } else {
                mPrivateFlags &= ~PFLAG_ALPHA_SET;
                invalidateViewProperty(true, false);
                mRenderNode.setAlpha(getFinalAlpha());
            }
        }
    }

具體代碼在這里不解釋犹赖,正是因?yàn)橛辛诉@個(gè)方法队他,我們的alpha動(dòng)畫才可以生效,所以你大概可以明白峻村,當(dāng)我們的object木有PropertyName的get/set方法的時(shí)候麸折,我們是沒法進(jìn)行動(dòng)畫實(shí)現(xiàn)的。

那么其實(shí)現(xiàn)在你就明白了屬性動(dòng)畫的強(qiáng)大了粘昨,它給予你非常大的自定義空間垢啼,你可以給任何對(duì)象添加你想要的實(shí)現(xiàn)。

然后如果你想實(shí)現(xiàn)一個(gè)動(dòng)畫監(jiān)聽器的話

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

當(dāng)然系統(tǒng)還提供了適配器來解決只選擇必要的方法重寫的功能张肾。

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

3.組合動(dòng)畫

雖然我們已經(jīng)可以實(shí)現(xiàn)簡單的動(dòng)畫芭析,但是產(chǎn)品總是會(huì)有很多神奇的想法,今天實(shí)現(xiàn)這么個(gè)動(dòng)畫吞瞪,明天實(shí)現(xiàn)這個(gè)動(dòng)畫馁启,各種奇怪的需求,你不得不尋找解決辦法芍秆,但是在屬性動(dòng)畫中惯疙,官方也給了相應(yīng)API來實(shí)現(xiàn),可以說是很不錯(cuò)的妖啥。

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

那么AnimatorSet.Builder的源碼如下:

public class Builder {
        private Node mCurrentNode;
        Builder(Animator anim) {
            mDependencyDirty = true;
            mCurrentNode = getNodeForAnimation(anim);
        }
        public Builder with(Animator anim) {
            Node node = getNodeForAnimation(anim);
            mCurrentNode.addSibling(node);
            return this;
        }
        public Builder before(Animator anim) {
            mReversible = false;
            Node node = getNodeForAnimation(anim);
            mCurrentNode.addChild(node);
            return this;
        }
        public Builder after(Animator anim) {
            mReversible = false;
            Node node = getNodeForAnimation(anim);
            mCurrentNode.addParent(node);
            return this;
        }
       public Builder after(long delay) {
            // setup dummy ValueAnimator just to run the clock
            ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
            anim.setDuration(delay);
            after(anim);
            return this;
        }
    }

Builder是構(gòu)建者迹栓,每次調(diào)用都會(huì)返回builder自身用于繼續(xù)構(gòu)建掉分,這四個(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í)行

通過這樣我們就可以控制動(dòng)畫播放順序,來實(shí)現(xiàn)想要的效果克伊。

        ObjectAnimator animator1 = ObjectAnimator.ofFloat(textView,"translationX",0.0f,200.0f,0f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(textView,"scaleX",1.0f,2.0f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(textView,"rotationX",0.0f,90.0f,0f);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        set.play(animator1).with(animator2).after(animator3);
        set.start();

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

在以前實(shí)現(xiàn)動(dòng)畫效果的時(shí)候我們可以用xml來實(shí)現(xiàn)酥郭,當(dāng)然屬性動(dòng)畫也不例外,有了xml代碼我們可以節(jié)省時(shí)間空間愿吹,很方便的調(diào)用不从,會(huì)達(dá)到一個(gè)代碼的復(fù)用,使用之前首先在res中建立animator(這個(gè)是為屬性動(dòng)畫準(zhǔn)備的)文件夾犁跪,那么在XML文件中我們一共可以使用如下三種標(biāo)簽:
<animator> 對(duì)應(yīng)代碼中的ValueAnimator
<objectAnimator> 對(duì)應(yīng)代碼中的ObjectAnimator
<set> 對(duì)應(yīng)代碼中的AnimatorSet

<set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:ordering="sequentially" >  
  
    <objectAnimator  
        android:duration="2000"  
        android:propertyName="translationX"  
        android:valueFrom="-500"  
        android:valueTo="0"  
        android:valueType="floatType" >  
    </objectAnimator>  
  
    <set android:ordering="together" >  
        <objectAnimator  
            android:duration="3000"  
            android:propertyName="rotation"  
            android:valueFrom="0"  
            android:valueTo="360"  
            android:valueType="floatType" >  
        </objectAnimator>  
  
        <set android:ordering="sequentially" >  
            <objectAnimator  
                android:duration="1500"  
                android:propertyName="alpha"  
                android:valueFrom="1"  
                android:valueTo="0"  
                android:valueType="floatType" >  
            </objectAnimator>  
            <objectAnimator  
                android:duration="1500"  
                android:propertyName="alpha"  
                android:valueFrom="0"  
                android:valueTo="1"  
                android:valueType="floatType" >  
            </objectAnimator>  
        </set>  
    </set>  
  
</set>  

這里搬郭神的一段代碼來椿息,這是使用xml來完成一個(gè)動(dòng)畫集合的效果,當(dāng)然如果寫單個(gè)動(dòng)畫只需要寫

<objectAnimator  
                android:duration="1500"  
                android:propertyName="alpha"  
                android:valueFrom="0"  
                android:valueTo="1"  
                android:valueType="floatType" >  
            </objectAnimator>  

一部分坷衍。

在java中的調(diào)用是這樣的

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

首先加載動(dòng)畫文件寝优,綁定視圖,最后啟動(dòng)動(dòng)畫枫耳。
屬性動(dòng)畫的介紹就這么多乏矾,肯定不如郭神講的詳細(xì),下面也給了郭神的文章鏈接,更多的請(qǐng)?jiān)L問钻心。

參考:http://blog.csdn.net/guolin_blog/article/details/43536355

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末凄硼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子捷沸,更是在濱河造成了極大的恐慌摊沉,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痒给,死亡現(xiàn)場離奇詭異说墨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)侈玄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門婉刀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人序仙,你說我怎么就攤上這事突颊。” “怎么了潘悼?”我有些...
    開封第一講書人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵律秃,是天一觀的道長。 經(jīng)常有香客問我治唤,道長棒动,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任宾添,我火速辦了婚禮船惨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘缕陕。我一直安慰自己粱锐,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開白布扛邑。 她就那樣靜靜地躺著怜浅,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蔬崩。 梳的紋絲不亂的頭發(fā)上恶座,一...
    開封第一講書人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音沥阳,去河邊找鬼跨琳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛桐罕,可吹牛的內(nèi)容都是我干的湾宙。 我是一名探鬼主播樟氢,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼侠鳄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起死宣,我...
    開封第一講書人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤伟恶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后毅该,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體博秫,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年眶掌,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了挡育。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡朴爬,死狀恐怖即寒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情召噩,我是刑警寧澤母赵,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站具滴,受9級(jí)特大地震影響凹嘲,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜构韵,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一周蹭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疲恢,春花似錦凶朗、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至萎攒,卻和暖如春遇八,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背耍休。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來泰國打工刃永, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人羊精。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓斯够,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子读规,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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

  • 參考于:http://blog.csdn.net/guolin_blog/article/details/4353...
    墨染書閱讀 2,925評(píng)論 0 2
  • 大致介紹 屬性動(dòng)畫系統(tǒng)是一個(gè)允許你對(duì)幾乎任何事情進(jìn)行的動(dòng)畫操作的健壯的框架抓督。你可以定義一個(gè)屬性動(dòng)畫來改變?nèi)魏螌?duì)象的...
    已遷至知乎_此不再維護(hù)閱讀 1,128評(píng)論 0 4
  • 北方 仍在南方,無夜的夜 你說你又會(huì)了新的曲目 你說你有兩個(gè)朝鮮族同學(xué) 你說北方的風(fēng)大 你說你的歡快和郁悶 你說你...
    顏?zhàn)彘L閱讀 473評(píng)論 3 1
  • 五月臨底束亏,種的幾棵雛菊才開花铃在。雖則只有幾朵,卻暗自欣喜老半天碍遍。雛菊花語是藏在心中的愛定铜,這小花清純含蓄招人疼。...
    麥草店主閱讀 271評(píng)論 2 1
  • 發(fā)現(xiàn)自己是個(gè)靜不下來的人怕敬。愛熱鬧揣炕,卻不得不安靜。我好痛苦东跪,好痛苦畸陡。好煩,好煩越庇。找不到讓自己安靜下來的書罩锐。找不到喜歡...
    白色薔薇香閱讀 201評(píng)論 0 0