Android中動畫的詳細講解及其使用

概述:

在Android動畫中悬钳,總共有兩種類型的動畫View Animation(視圖動畫)和Property Animator(屬性動畫)盐捷;
其中 :
a.View Animation包括Tween Animation(補間動畫)和Frame Animation(逐幀動畫);
b.Property Animator包括ValueAnimator和ObjectAnimation默勾;
首先碉渡,直觀上,他們有如下三點不同
1母剥、引入時間不同:View Animation是API Level 1就引入的滞诺。Property Animation是API Level 11引入的,即Android 3.0才開始有Property Animation相關的API环疼。
2习霹、所在包名不同:View Animation在包android.view.animation中。而Property Animation API在包 android.animation中秦爆。
3序愚、動畫類的命名不同:View Animation中動畫類取名都叫XXXXAnimation,而在Property Animator中動畫類的取名則叫XXXXAnimator

大家都知道逐幀動畫主要是用來實現(xiàn)動畫的,而補間動畫才能實現(xiàn)控件的漸入漸出等限、移動爸吮、旋轉(zhuǎn)和縮放的;而Property Animator是在Android 3.0版本才引入的望门,之前是沒有的形娇。大家可能會覺得補間動畫和逐幀動畫已經(jīng)很全了,為什么還要引入Property Animator呢筹误?

1桐早、為什么引入Property Animator(屬性動畫)
我提出一個假設:請問大家,如何利用補間動畫來將一個控件的背景色在一分鐘內(nèi)從綠色變?yōu)榧t色厨剪?這個效果想必沒辦法僅僅通過改變控件的漸入漸出哄酝、移動、旋轉(zhuǎn)和縮放來實現(xiàn)吧祷膳,而這個效果是可以通過Property Animator完美實現(xiàn)的
這就是第一個原因:Property Animator能實現(xiàn)補間動畫無法實現(xiàn)的功能
大家都知道陶衅,補間動畫和逐幀動畫統(tǒng)稱為View Animation,也就是說這兩個動畫只能對派生自View的控件實例起作用直晨;而Property Animator則不同搀军,從名字中可以看出屬性動畫,應該是作用于控件屬性的勇皇!正因為屬性動畫能夠只針對控件的某一個屬性來做動畫罩句,所以也就造就了他能單獨改變控件的某一個屬性的值!比如顏色敛摘!這就是Property Animator能實現(xiàn)補間動畫無法實現(xiàn)的功能的最重要原因门烂。
我們得到了第二點不同:View Animation僅能對指定的控件做動畫,而Property Animator是通過改變控件某一屬性值來做動畫的着撩。
假設我們將一個按鈕從左上角利用補間動畫將其移動到右下角诅福,在移動過程中和移動后匾委,這個按鈕都是不會響應點擊事件的。這是為什么呢氓润?因為補間動畫僅僅轉(zhuǎn)變的是控件的顯示位置而已赂乐,并沒有改變控件本身的值。View Animation的動畫實現(xiàn)是通過其Parent View實現(xiàn)的咖气,在View被drawn時Parents View改變它的繪制參數(shù)挨措,這樣雖然View的大小或旋轉(zhuǎn)角度等改變了,但View的實際屬性沒變崩溪,所以有效區(qū)域還是應用動畫之前的區(qū)域浅役;我們看到的效果僅僅是系統(tǒng)作用在按鈕上的顯示效果,利用動畫把按鈕從原來的位置移到了右下角伶唯,但按鈕內(nèi)部的任何值是沒有變化的觉既,所以按鈕所捕捉的點擊區(qū)域仍是原來的點擊區(qū)域。(下面會舉例來說明這個問題)
這就得到了第三點不同:補間動畫雖能對控件做動畫乳幸,但并沒有改變控件內(nèi)部的屬性值瞪讼。而Property Animator則是恰恰相反,Property Animator是通過改變控件內(nèi)部的屬性值來達到動畫效果的

2粹断、舉例說明補間動畫的點擊區(qū)域問題

下面我們就利用TranslateAnimation來做一個移動動畫的例子符欠,看它的點擊區(qū)域是否會變搁进。
我們先來看看效果


image.png

在效果圖中坠非,首先,我給textview添加了點擊響應忧吟,當點擊textview時养筒,會彈出Toast曾撤。
然后,當我點擊按鈕的時候晕粪,textview開始向右下角移動盾戴。
從結(jié)果中可以看出,在移動前兵多,點擊textview是可以彈出toast的的,在移動后橄仆,點擊textview時則沒有響應剩膘,相反,點擊textview的原來所在區(qū)域則會彈出toast.

這就論證了不同第三點:補間動畫雖能對控件做動畫盆顾,但并沒有改變控件內(nèi)部的屬性值

Android中常用的動畫都在這里了怠褐,包含了基本的動畫【透明度動畫,縮放動畫您宪,旋轉(zhuǎn)動畫奈懒,位移動畫】奠涌;還有就是這四種動畫的組合實現(xiàn); 還有布局動畫磷杏,就是在加載布局時的動畫溜畅;還有Activity跳轉(zhuǎn)的動畫。 效果圖如下:


a.gif

1. Android基礎動畫

如果是xml的方式寫要在res下創(chuàng)建anim文件夾內(nèi)寫

透明度動畫

xml:

 <?xml version="1.0" encoding="utf-8"?>
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <alpha
         android:duration="1000"
         android:fromAlpha="0.0"
         android:toAlpha="1.0"
         />
 </set>

代碼:

        AlphaAnimation animation = new AlphaAnimation(0, 1);
        animation.setDuration(3000);
        animation.setFillAfter(true);
        mImg.setAnimation(animation);

縮放動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:duration="1000"
        android:fromXScale="0"
        android:fromYScale="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1"
        android:toYScale="1" />
</set>

代碼:

 /**
 * 第一個參數(shù)fromX為動畫起始時 X坐標上的伸縮尺寸
 * 第二個參數(shù)toX為動畫結(jié)束時 X坐標上的伸縮尺寸
 * 第三個參數(shù)fromY為動畫起始時Y坐標上的伸縮尺寸
 * 第四個參數(shù)toY為動畫結(jié)束時Y坐標上的伸縮尺寸
 * 說明: 0.0表示收縮到?jīng)]有;1.0表示正常無伸縮;值小于1.0表示收縮;值大于1.
 * 第五個參數(shù)pivotXType為動畫在X軸相對于物件位置類型
 * 第六個參數(shù)pivotXValue為動畫相對于物件的X坐標的開始位置
 * 第七個參數(shù)pivotXType為動畫在Y軸相對于物件位置類型
 * 第八個參數(shù)pivotYValue為動畫相對于物件的Y坐標的開始位置
 */
    private void playAnimator(View view) {
        ObjectAnimator objectAnimatorX = ObjectAnimator.ofFloat(view, "scaleX", 1.0f, 1.3f, 0.9f, 1.15f, 0.95f, 1.02f, 1.0f);
        ObjectAnimator objectAnimatorY = ObjectAnimator.ofFloat(view, "scaleY", 1.0f, 1.3f, 0.9f, 1.15f, 0.95f, 1.02f, 1.0f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.play(objectAnimatorX).with(objectAnimatorY);
        animatorSet.setDuration(1000);
        animatorSet.start();
    }
Animation animation = new ScaleAnimation(0, 1
animation.setDuration(1000);
iv.startAnimation(animation);

旋轉(zhuǎn)動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
</set>

代碼:

    /**
     * 第一個參數(shù)fromDegrees為動畫起始時角度
     * 第二個參數(shù)toDegrees為動畫結(jié)束角度
     * 第三個參數(shù)pivotXType為動畫在X軸相對于物件位置類型
     * 第四個參數(shù)pivotXValue為動畫相對于物件的X坐標的開始位置
     * 第五個參數(shù)pivotXType為動畫在Y軸相對于物件位置類型
     * 第六個參數(shù)pivotYValue為動畫相對于物件的Y坐標的開始位置
     */
    Animation animation = new RotateAnima
    animation.setDuration(1000);
    iv.startAnimation(animation);

位移動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="2000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="500"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="0" />
</set>

代碼:

    /**
     * 第一個參數(shù)fromDegrees為動畫起始時角度
     * 第二個參數(shù)toDegrees為動畫結(jié)束角度
     * 第三個參數(shù)pivotXType為動畫在X軸相對于物件位置類型
     * 第四個參數(shù)pivotXValue為動畫相對于物件的X坐標的開始位置
     * 第五個參數(shù)pivotXType為動畫在Y軸相對于物件位置類型
     * 第六個參數(shù)pivotYValue為動畫相對于物件的Y坐標的開始位置
     */
     Animation animation = new RotateAnima
     animation.setDuration(1000);
     iv.startAnimation(animation);
     /**
      * 第一個參數(shù)fromXDelta為動畫起始時的x坐標
      * 第二個參數(shù)toXDelta為動畫結(jié)束時的x坐標
      * 第三個參數(shù)fromYDelta為動畫起始時的y坐標
      * 第四個參數(shù)toYDelta為動畫結(jié)束時的y坐標
      */
      Animation animation = new Translat
      animation.setDuration(2000);
      /**設置插值器:先加速极祸,后減速**/
      animation.setInterpolator(new Acce
      iv.startAnimation(animation);

2.組合動畫

先播放縮放動畫慈格,完成后播放旋轉(zhuǎn)動畫

  Animation animation = AnimationUtils.loadAnimation(this, R.anim.scale);
               iv.startAnimation(animation);
               final Animation animation2 = AnimationUtils.loadAnimation(this, R.anim.rotate);
               animation.setAnimationListener(new Animation.AnimationListener() {
                   @Override
                   public void onAnimationStart(Animation animation) {

                   }

                   @Override
                   public void onAnimationEnd(Animation animation) {

                       iv.startAnimation(animation2);
                   }

                   @Override
                   public void onAnimationRepeat(Animation animation) {

                   }
               });

先播放旋轉(zhuǎn)動畫,完成后播放位移動畫遥金,在xml中設置第二個動畫執(zhí)行的等待時間

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="360" />
    <translate
        android:duration="1000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="500"
        android:startOffset="1000"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="0" />
</set>

重復的透明度動畫-閃爍

AlphaAnimation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
                alphaAnimation.setDuration(1000);
                alphaAnimation.setRepeatCount(10);
                /**倒序重復REVERSE  正序重復RESTART**/
                alphaAnimation.setRepeatMode(Animation.REVERSE);
                iv.startAnimation(alphaAnimation);

重復的位移動畫-抖動

 Animation translateAnimation = new TranslateAnimation(-10, 10, 0, 0);
                translateAnimation.setDuration(100);
                translateAnimation.setRepeatCount(10);
                /**倒序重復REVERSE  正序重復RESTART**/
                translateAnimation.setRepeatMode(Animation.REVERSE);
                iv.startAnimation(translateAnimation);

3.幀動畫

在drawable文件夾下建立文件

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
 >
   <item android:drawable="@mipmap/windmill_1"
       android:duration="500">
   </item>
   <item android:drawable="@mipmap/windmill_2"
       android:duration="500">
   </item>
   <item android:drawable="@mipmap/windmill_3"
       android:duration="500">
   </item>
   <item android:drawable="@mipmap/windmill_4"
       android:duration="500">
   </item>
   <item android:drawable="@mipmap/windmill_5"
       android:duration="500">
   </item>
   <item android:drawable="@mipmap/windmill_6"
       android:duration="500">
   </item>
   <item android:drawable="@mipmap/windmill_7"
       android:duration="500">
   </item>

</animation-list>

在activity中調(diào)用

   iv.setImageResource(R.drawable.ring_animation);
               AnimationDrawable animationDrawable = (AnimationDrawable) iv.getDrawable();
               animationDrawable.start();

4.布局動畫 這是一個ListView的加載布局動畫

先建立動畫文件,從透明到不透明并且大小從0到原大小

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator" >

    <scale
        android:duration="1000"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0" />
    <alpha
        android:duration="1000"
        android:fromAlpha="0"
        android:toAlpha="1.0" />
</set>

在activity中的用法

 ListView listView = (ListView) findViewById(R.id.listview);
        List<String> datas = new ArrayList<>();
        for (int i = 0; i < 18; i++) {
            datas.add("萬能適配器測試" + i);
        }
        LayoutAnimationController layoutAnimationController= new        LayoutAnimationController(AnimationUtils.loadAnimation(this, R.anim.zoom_in));
        layoutAnimationController.setOrder(LayoutAnimationController.ORDER_NORMAL);
        listView.setLayoutAnimation(layoutAnimationController);
        listView.setAdapter(new CommonAdapter<String>(this, datas, R.layout.item) {

            @Override
            protected void convertView(View item, String s) {
                TextView textView = CommonViewHolder.get(item, R.id.textView);
                textView.setText(s);
            }
        });

5.Activity跳轉(zhuǎn)動畫

退出動畫:從不透明到透明并且大小從原大小到0

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:zAdjustment="top" >

    <scale
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%p"
        android:pivotY="50%p"
        android:toXScale="0.1"
        android:toYScale="0.1" />

    <alpha
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromAlpha="1.0"
        android:toAlpha="0" />

</set>

進入動畫:從透明到不透明并且大小從0到原大小

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator" >

    <scale
        android:duration="1000"
        android:fromXScale="0.1"
        android:fromYScale="0.1"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.0"
        android:toYScale="1.0" />
    <alpha
        android:duration="1000"
        android:fromAlpha="0"
        android:toAlpha="1.0" />
</set>

在Activity中的用法

  startActivity(new Intent(this,SecondActivity.class));
                overridePendingTransition(R.anim.zoom_in,R.anim.zoom_out);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末浴捆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子稿械,更是在濱河造成了極大的恐慌选泻,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,366評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件美莫,死亡現(xiàn)場離奇詭異页眯,居然都是意外死亡,警方通過查閱死者的電腦和手機茂嗓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評論 3 395
  • 文/潘曉璐 我一進店門餐茵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人述吸,你說我怎么就攤上這事忿族。” “怎么了蝌矛?”我有些...
    開封第一講書人閱讀 165,689評論 0 356
  • 文/不壞的土叔 我叫張陵道批,是天一觀的道長。 經(jīng)常有香客問我入撒,道長隆豹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評論 1 295
  • 正文 為了忘掉前任茅逮,我火速辦了婚禮璃赡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘献雅。我一直安慰自己碉考,他們只是感情好,可當我...
    茶點故事閱讀 67,942評論 6 392
  • 文/花漫 我一把揭開白布挺身。 她就那樣靜靜地躺著侯谁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上墙贱,一...
    開封第一講書人閱讀 51,727評論 1 305
  • 那天热芹,我揣著相機與錄音,去河邊找鬼惨撇。 笑死伊脓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的串纺。 我是一名探鬼主播丽旅,決...
    沈念sama閱讀 40,447評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼纺棺!你這毒婦竟也來了榄笙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評論 0 276
  • 序言:老撾萬榮一對情侶失蹤祷蝌,失蹤者是張志新(化名)和其女友劉穎茅撞,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巨朦,經(jīng)...
    沈念sama閱讀 45,820評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡米丘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,990評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了糊啡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拄查。...
    茶點故事閱讀 40,127評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖棚蓄,靈堂內(nèi)的尸體忽然破棺而出堕扶,到底是詐尸還是另有隱情,我是刑警寧澤梭依,帶...
    沈念sama閱讀 35,812評論 5 346
  • 正文 年R本政府宣布稍算,位于F島的核電站,受9級特大地震影響役拴,放射性物質(zhì)發(fā)生泄漏糊探。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,471評論 3 331
  • 文/蒙蒙 一河闰、第九天 我趴在偏房一處隱蔽的房頂上張望科平。 院中可真熱鬧,春花似錦姜性、人聲如沸匠抗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春印机,著一層夾襖步出監(jiān)牢的瞬間矢腻,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評論 1 272
  • 我被黑心中介騙來泰國打工射赛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留多柑,地道東北人。 一個月前我還...
    沈念sama閱讀 48,388評論 3 373
  • 正文 我出身青樓楣责,卻偏偏與公主長得像竣灌,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子秆麸,可洞房花燭夜當晚...
    茶點故事閱讀 45,066評論 2 355

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