使用兩種方式完成四種彈性動(dòng)畫

前言

??最近這段時(shí)間對(duì)彈性動(dòng)畫比較感興趣宁昭,空閑就做了一下彈性動(dòng)畫的實(shí)現(xiàn)骤菠。網(wǎng)上對(duì)彈性動(dòng)畫的實(shí)現(xiàn)其實(shí)是有3種铃肯,屬性動(dòng)畫設(shè)置spring插值器为朋、facebook出的rebound以及google出的SpringAnimation臂拓。考慮到android的google背景以及想重溫一下屬性動(dòng)畫的使用习寸,本博實(shí)現(xiàn)了第一種和第三種胶惰。

最終實(shí)現(xiàn)效果

springAni.gif

??注意上述動(dòng)態(tài)圖界面的title,第一個(gè)界面是屬性動(dòng)畫差值器的實(shí)現(xiàn)霞溪,第二個(gè)界面是SpringAnimation的實(shí)現(xiàn)孵滞。每一種實(shí)現(xiàn)都做了四種常見(jiàn)的動(dòng)畫操作:縮放、平移鸯匹、旋轉(zhuǎn)坊饶、淡入淡出。

思路及代碼

??所謂“彈性動(dòng)畫”殴蓬,其實(shí)就是控件的某個(gè)屬性值在到達(dá)某個(gè)值之后在該值的左右來(lái)回變化(變得比改之大匿级,或變得比該值小),最終穩(wěn)定在該值的效果痘绎。這種變化的動(dòng)畫很像彈簧津函,所以就叫做“彈性動(dòng)畫”。這種變化作用在view的縮放參數(shù)(scaleX孤页、scaleY)尔苦、平移參數(shù)(transactionX、transactionY)散庶、旋轉(zhuǎn)參數(shù)(rotation)、透明度參數(shù)(alpha)上會(huì)有物理運(yùn)動(dòng)的那種平滑過(guò)渡的效果凌净,比直接到達(dá)該值的那種生硬好很多很多悲龟,這也是“彈性動(dòng)畫”的意義了。

??插值器實(shí)現(xiàn)

??屬性動(dòng)畫的彈性效果實(shí)現(xiàn)冰寻,是利用插值器须教。而選擇合適的插值器函數(shù)至關(guān)重要,網(wǎng)上的一篇文章直接給出了函數(shù):pow(2, -10 * x) * sin((x - factor / 4) * (2 * PI) / factor) + 1斩芭,我們就可以利用這個(gè)函數(shù)創(chuàng)建自己的插值器實(shí)現(xiàn)此效果:

public class SpringInterpolator implements Interpolator {

    private float factor;

    public SpringInterpolator(float factor) {
        this.factor = factor;
    }

    @Override
    public float getInterpolation(float input) {
        //factor = 0.4
//        pow(2, -10 * x) * sin((x - factor / 4) * (2 * PI) / factor) + 1

        return (float) (Math.pow(2, -10 * input) * Math.sin((input - factor / 4) * (2 * Math.PI) / factor) + 1);
    }
}

??需要注意的是轻腺,此插值器除了在0~1之間線性變化的input這個(gè)輸入?yún)?shù)外,還有一個(gè)factor的輸入?yún)?shù)划乖。那此參數(shù)是做什么的呢贬养?我們可以做一個(gè)實(shí)驗(yàn),做實(shí)驗(yàn)的地方是在這個(gè)網(wǎng)站琴庵,此處的Library選擇Spring误算,然后Equation中的內(nèi)容就變成了我們上面說(shuō)的那個(gè)方程。我們看到當(dāng)factor為0.4時(shí)迷殿,曲線圖是這樣的:

factor0.4.png

??我們修改factor的值為0.1儿礼,曲線圖變成了這樣:

factor0.1.png

??再次修改factor的值為0.9,曲線圖是這樣:

factor0.9.png

??由上述三圖就可以得出結(jié)論:factor的值越小庆寺,值來(lái)回變化的次數(shù)越多蚊夫,對(duì)應(yīng)到具體的動(dòng)畫就是:factor值越小,view來(lái)回縮放的次數(shù)越多懦尝,平移到指定位置后在指定位置上下或左右擺動(dòng)的次數(shù)也越多知纷,旋轉(zhuǎn)和淡入淡出類似。

??下面看一下屬性動(dòng)畫的實(shí)現(xiàn)部分陵霉,因?yàn)閷傩詣?dòng)畫的使用都是差不多屈扎,這里只列出其中的一次使用:

//創(chuàng)建兩個(gè)對(duì)象動(dòng)畫的實(shí)例和將這個(gè)實(shí)例組合起來(lái)的組合對(duì)象實(shí)例
ObjectAnimator objectAnimator0 = null;
ObjectAnimator objectAnimator1 = null;
AnimatorSet animatorSet = new AnimatorSet();

//指定修改view的哪個(gè)屬性及屬性的起始值和結(jié)束值
objectAnimator0 = ObjectAnimator.ofFloat(imageview, "scaleX", 1.0f, 2.0f);
objectAnimator1 = ObjectAnimator.ofFloat(imageview, "scaleY", 1.0f, 2.0f);

//指定兩個(gè)對(duì)象動(dòng)畫的執(zhí)行順序
animatorSet.playTogether(objectAnimator0, objectAnimator1);
//指定兩個(gè)動(dòng)畫組合之后的執(zhí)行時(shí)間
animatorSet.setDuration(2500);
//指定插值器
animatorSet.setInterpolator(new SpringInterpolator(0.3f));
//啟動(dòng)動(dòng)畫
animatorSet.start();
        

??屬性動(dòng)畫插值器值得說(shuō)的就這么多(插值器函數(shù)中factor的作用、屬性動(dòng)畫的基本使用)撩匕,后面會(huì)給出完整源碼鹰晨。

??SpringAnimation實(shí)現(xiàn)

??Google有專門的一個(gè)包用于實(shí)現(xiàn)此彈性效果,在gradle腳本文件中添加"compile 'com.android.support:support-dynamic-animation:25.+'"引入此包。這個(gè)包的使用也很簡(jiǎn)單模蜡,這里給出一個(gè)其中一種動(dòng)畫的實(shí)現(xiàn)代碼:

//創(chuàng)建兩個(gè)彈性動(dòng)畫對(duì)象
SpringAnimation springAnimation0 = null;
SpringAnimation springAnimation1 = null;

//指定處理view的哪個(gè)屬性漠趁,以及view此屬性的最終值(2.0f)
springAnimation0 = new SpringAnimation(imageview, new FloatPropertyCompat<ImageView>("scaleX") {
        @Override
        public float getValue(ImageView object) {
            float scaleX = object.getScaleX();
            return scaleX;
        }
    
        @Override
        public void setValue(ImageView object, float value) {
            object.setScaleX(value);
        }
    }, 2.0f);
    springAnimation1 = new SpringAnimation(imageview, new FloatPropertyCompat<ImageView>("scaleY") {
        @Override
        public float getValue(ImageView object) {
            float scaleY = object.getScaleY();
            return scaleY;
        }
    
        @Override
        public void setValue(ImageView object, float value) {
            object.setScaleY(value);
        }
    }, 2.0f);
    
//作一些設(shè)置,要不然肉眼看不出來(lái)生效
springAnimation0.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_ALPHA);
springAnimation1.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_ALPHA);

//指定此彈性動(dòng)畫的彈性阻尼
springAnimation0.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY);
//指定此彈性動(dòng)畫的彈性生硬度
springAnimation0.getSpring().setStiffness(SpringForce.STIFFNESS_VERY_LOW);

//如上
springAnimation1.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_HIGH_BOUNCY);
springAnimation1.getSpring().setStiffness(SpringForce.STIFFNESS_VERY_LOW);

//啟動(dòng)動(dòng)畫
springAnimation0.start();
springAnimation0.start();
        

??需要說(shuō)的幾個(gè)點(diǎn):

  • 此處的彈性動(dòng)畫只指定了屬性的最終值忍疾,而沒(méi)有指定屬性的起始值闯传。因?yàn)樵摪鼤?huì)根據(jù)當(dāng)前view的位置自動(dòng)獲取起始值,所以無(wú)需我們指定卤妒;
  • FloatPropertyCompat甥绿,雖然代碼量看著多,其實(shí)不難则披。構(gòu)造函數(shù)中傳入相關(guān)view屬性共缕,兩個(gè)抽象方法完成對(duì)此屬性的讀寫;
  • springAnimation0.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_ALPHA);在做縮放動(dòng)畫時(shí)士复,setMinimumVisibleChange方法的調(diào)用是必須的图谷,如果不調(diào)用縮放就沒(méi)有彈性效果。我也是看了一部分此包的實(shí)現(xiàn)源碼才發(fā)現(xiàn)這點(diǎn)的阱洪。后面的完整代碼里會(huì)針對(duì)不同的動(dòng)畫給出不同的setMinimumVisibleChange方法調(diào)用便贵;
  • setDampingRatio,就是設(shè)置摩擦力的冗荸,摩擦力越大彈起來(lái)越費(fèi)勁承璃,摩擦力越小彈起來(lái)越輕松;
  • setStiffness蚌本,這個(gè)是設(shè)置彈性生硬度的绸硕。顯示中彈簧給人的感覺(jué)是,如果它鋼性越強(qiáng)彈起來(lái)也越費(fèi)勁鋼性不那么強(qiáng)的彈起來(lái)輕松魂毁;
  • 查了一篇資料玻佩,資料中說(shuō),dampingRatio(即摩擦力)越大席楚,擺動(dòng)次數(shù)越少咬崔,反之則越多;stiffness(即生硬度烦秩、鋼性)越大垮斯,擺動(dòng)時(shí)間越短,反之則越長(zhǎng)只祠。通俗解釋兜蠕,可感知。

總結(jié)

??使用插值器實(shí)現(xiàn)彈性動(dòng)畫抛寝,最核心的是找到彈性插值器的函數(shù)熊杨,而次函數(shù)已經(jīng)是前人栽樹后人乘涼了曙旭,查資料可以查得;而SpringAnimation的實(shí)現(xiàn)晶府,重點(diǎn)是要懂SpringAnimation的基本使用和知道怎么使用setMinimumVisibleChange使彈性效果肉眼可見(jiàn)桂躏。

這里是完整源碼

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市川陆,隨后出現(xiàn)的幾起案子剂习,更是在濱河造成了極大的恐慌,老刑警劉巖较沪,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鳞绕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡尸曼,警方通過(guò)查閱死者的電腦和手機(jī)们何,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)骡苞,“玉大人垂蜗,你說(shuō)我怎么就攤上這事楷扬〗庥模” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵烘苹,是天一觀的道長(zhǎng)躲株。 經(jīng)常有香客問(wèn)我,道長(zhǎng)镣衡,這世上最難降的妖魔是什么霜定? 我笑而不...
    開(kāi)封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮廊鸥,結(jié)果婚禮上望浩,老公的妹妹穿的比我還像新娘。我一直安慰自己惰说,他們只是感情好磨德,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著吆视,像睡著了一般典挑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上啦吧,一...
    開(kāi)封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天您觉,我揣著相機(jī)與錄音,去河邊找鬼授滓。 笑死琳水,一個(gè)胖子當(dāng)著我的面吹牛肆糕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播炫刷,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼擎宝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了浑玛?” 一聲冷哼從身側(cè)響起绍申,我...
    開(kāi)封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顾彰,沒(méi)想到半個(gè)月后极阅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涨享,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年筋搏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厕隧。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奔脐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吁讨,到底是詐尸還是另有隱情髓迎,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布排龄,位于F島的核電站翎朱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏争舞。R本人自食惡果不足惜澈灼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望流译。 院中可真熱鬧者疤,春花似錦福澡、人聲如沸驹马。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)效拭。三九已至,卻和暖如春缎患,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背肮街。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工嫉父, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人绕辖。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓引镊,卻偏偏與公主長(zhǎng)得像篮条,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子狼牺,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

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