Android Animation解析

在app中增加一些動畫效果能使我們的app更加絢麗,本文主要總結android中的Animation

Android中的Animation可以分為三種,View Animation,Drawable Animation ,Property Animation,其中第一種比較簡單,只能實現一些簡單的平移,縮放,旋轉,透明度漸變的基本動畫效果,第二種可以實現一種逐幀動畫效果,而第三種屬性動畫比較復雜,Android 3.0之后出現,view動畫能實現的它都能實現,除此之外還能實現很多其他的動畫效果。

1.View動畫,它的實現方式有兩種,XML方式和javacode方式

XML方式:

  • 新建項目,在res目錄中新建anim文件夾
  • 在anim目錄中新建動畫代碼
  • 載入XML動畫效果

直接上代碼
透明度漸變動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <!--alpha漸變透明度動畫
   fromAlpha 代表起始時透明度
   toAlpha 代表終止時透明度
   duration 動畫持續事件 毫秒為單位-->
<alpha
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:duration="1000"/>
</set>

旋轉動畫

  <?xml version="1.0" encoding="utf-8"?>
  <set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--旋轉動畫
   interpolator 動畫插值器,跟伸縮動畫一樣
   fromDegress 動畫起始時物件的角度
   toDegress 動畫結束時物件旋轉的角度,當角度為負數表示逆時針旋轉,當角度為正數表示順時針旋轉
                (負數from——to正數:順時針旋轉)
                (負數from——to負數:逆時針旋轉)
                (正數from——to正數:順時針旋轉)
                (正數from——to負數:逆時針旋轉)
   pivotX,pivotY表示旋轉的x,y坐標,0%-100%取值。50%表示中點
   repeatMode代表重復類型:重復類型有兩個值,reverse表示倒序回放,restart表示從頭播放
   repeatCount代表重復次數,重復次數是int型
   -->
   <rotate
    android:duration="3000"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="+350"
    android:repeatMode="restart"
    android:repeatCount="6"
    />
</set>

尺寸伸縮動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<!--漸變尺寸伸縮動畫
   duration 漸變時間
   interpolator 指定一個動畫的插入器
   有三種動畫的插入器
   accelerate_decelerate_interpolator 加速-減速動畫插入器
   accelerate_interpolator 加速動畫插入器
   decelerate_interpolator 減速動畫插入器
    fromXScale 動畫起始時x坐標的伸縮尺寸
    toXScale 動畫結束時x坐標的伸縮尺寸

    fromYScale 動畫起始時Y坐標的伸縮尺寸
    toYScale 動畫結束時Y坐標的伸縮尺寸
    0.0表示沒有,1.0表示正常無收縮,值小于1.0表示收縮,值大于1.0表示放大
    pivotX 屬性為動畫相對于物件的X坐標的開始位置
    pivotY 屬性為動畫相對于物件的Y坐標的開始位置
    從0%-100%開始取值, 50%表示物件的X或者Y方向坐標上的中點位置
    fillAfter 當設置為true,該動畫轉化在動畫結束后被應用-->
  <scale
    android:duration="1000"
    android:fillAfter="false"
    android:fromXScale="0.0"
    android:fromYScale="0.0"
    android:toXScale="1.4"
    android:toYScale="1.4"
    android:pivotX="50%"
    android:pivotY="50%"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
</set>

位移動畫

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
 <!--位置轉移動畫
   fromXDelta 動畫開始時X坐標位置
   fromYDelta 動畫開始時Y坐標位置
   toXDelta 動畫結束時X坐標位置
   toYDelta 動畫結束時Y坐標位置
   -->
<translate
    android:duration="2000"
    android:fromXDelta="30"
    android:fromYDelta="30"
    android:toXDelta="-80"
    android:toYDelta="300"
    />
</set>

載入XML動畫效果

switch (v.getId()) {
        case R.id.bt_alpha:
            //載入動畫
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_scale:
            //載入動畫
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_translate:
            //載入動畫
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_rotate:
            //載入動畫
            mAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
            mIv.startAnimation(mAnimation);
            break;
        default:
            break;
    }

和點擊事件一樣,動畫也具有監聽,只需要我們的activity實現AnimationListener接口就行,我們可以在動畫開始或者結束或者重復做一些別的操作

@Override
public void onAnimationStart(Animation animation) {//動畫開始
}

@Override
public void onAnimationEnd(Animation animation) {//動畫結束
}

@Override
public void onAnimationRepeat(Animation animation) {//動畫重復
}

此外動畫還有其他的屬性,比如比較常用的android:repeatCount(XML中定義,表示重復次數),android:repeatMode(表示重復模式,重復類型有兩個值,reverse表示倒序回放,restart表示從頭播放),android:interpolator(設置差值器,這個在屬性動畫中會詳細講解)

上面講了View動畫的XML實現方式,下面介紹javacode實現方式,javacode的實現方式也很簡單(不需要新建XML)

 switch (v.getId()) {
        case R.id.bt_alpha:
            mAnimation = new AlphaAnimation(0.1f, 0.1f);//新建一個透明度變化的動畫
            mAnimation.setDuration(2000);//設置動畫事件
            mIv.startAnimation(mAnimation);//開始動畫
            break;
        case R.id.bt_scale:
            //漸變尺寸縮放動畫效果
            mAnimation = new ScaleAnimation(0.0f, 2.0f, 1.5f, 1.5f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 0.0f);
            mAnimation.setDuration(2000);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_translate:
            //移動動畫效果
            mAnimation = new TranslateAnimation(0, 100, 0, 100);
            mAnimation.setDuration(2000);
            mIv.startAnimation(mAnimation);
            break;
        case R.id.bt_rotate:
            //旋轉動畫效果,這里是旋轉360°
            mAnimation = new RotateAnimation(0.0f, 360.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            mAnimation.setDuration(2000);
            mIv.startAnimation(mAnimation);
            break;
        default:
            break;

看效果


View動畫2.gif

2.Drawable Animation動畫,它是把一幀一幀拼起來組成動畫

  • 在res/drawable目錄添加圖片素材
Paste_Image.png
  • 在drawable文件夾中添加動畫幀布局文件

      <?xml version="1.0" encoding="utf-8"?>
      <!--
          根標簽為animation-list,其中oneshot代表著是否只展示一遍,設置為false會不停的循環播放動畫  
          根標簽下,通過item標簽對動畫中的每一個圖片進行聲明  
          android:duration 表示展示所用的該圖片的時間長度  
      -->
      <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
          android:oneshot="false" >
          <item
      android:drawable="@drawable/cmmusic_progress_1"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_2"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_3"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_4"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_5"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_6"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_7"
      android:duration="150">
          </item>
          <item
      android:drawable="@drawable/cmmusic_progress_8"
      android:duration="150">
          </item>
      </animation-list>
    

引入XML布局文件實現動畫

   //給ImageView設置drawable
    imgPic.setImageResource(R.drawable.loading_anim);
    //給動畫資源賦值
    animationDrawable = (AnimationDrawable) imgPic.getDrawable();
  animationDrawable.start();//開始動畫
   animationDrawable.stop(); //停止動畫

實現效果類似于下拉加載的菊花轉

3.屬性動畫

之所以引入屬性動畫有三點原因:

  • 屬性動畫不僅可以對view操作,也能對非view的對象進行操作
  • 屬性動畫不單單具有View動畫的那些基本動畫效果,也具有其他動畫效果
  • View動畫只是改變了View的顯示效果而已,而不會真正去改變View的屬性。而屬性動畫不單單是一種視覺上的動畫,它是真正的改變了view的位置

屬性動畫實際上是一種不斷地對值進行操作的機制,并將值賦值到指定對象的指定屬性上,可以是任意對象的任意屬性。所以我們仍然可以將一個View進行移動或者縮放,但同時也可以對自定義View中的Point對象進行動畫操作了。我們只需要告訴系統動畫的運行時長,需要執行哪種類型的動畫,以及動畫的初始值和結束值,剩下的工作就可以全部交給系統去完成了。

看完上面這段話還是不理解屬性動畫,那我們用起來就可以了
屬性動畫有三個類特別重要,分別是ValueAnimator,ObjectAnimator,AnimatorSet,前兩個都是動畫的執行類,用來執行屬性動畫的,而且ObjectAnimator是集成ValueAnimator的,而AnimatorSet顧名思義是動畫的集合,用它來實現組合動畫,我們來分別認識這三個類

VlaueAnimator

這個是屬性動畫最核心的類了,前面已經提到,屬性動畫實際上是一種不斷對值進行操作的機制,并將值賦值到指定對象的指定屬性上,而初始值和結束值的動畫過渡就是這個類來負責計算的,我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。除此之外,ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設置監聽器等。

使用ValueAnimator

ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);  //值從0平滑到1,除此之外還可以用ofInt方法
anim.setDuration(300);  //動畫持續時間
anim.start(); //動畫開始

但是這段代碼看不到任何界面效果,我們可以添加一個監聽器方法,在動畫執行過程中用不斷進行回調

anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  
@Override  
public void onAnimationUpdate(ValueAnimator animation) {  
    float currentValue = (float) animation.getAnimatedValue();  
    Log.d("TAG", "cuurent value is " + currentValue);  
}  
}); 

可以通過日志看到動畫確實在執行

ObjectAnimator

ValueAnimator只是實現值的平滑過渡,使用場景并不是很多,而ObjectAnimator可以對任意對象的任意屬性進行操作,一般我們是對view進行操作,因為ObjectAnimator是繼承ValueAnimator,所以在ValueAnimator使用的方法在ObjectAnimator中也可以正常使用,直接上代碼

        float curTrans = mIv.getTranslationX();//得到
        ObjectAnimator animator = ObjectAnimator.ofFloat(mIv, "translationX", curTrans,-500 ,curTrans);
        animator.setDuration(5000);
        animator.start();

上面的代碼實現了平移的操作,其他例如透明度變化,旋轉和伸縮都類似,不同的是ofFloat里面的參數發生變化

  • ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); //透明度變化
  • ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f); //旋轉
  • ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f); 縮放

第一個參數是view,第二個參數是動畫類型,后面的參數根據動畫類型的不同參數也不一樣,關于第二個類型,雖然view里面沒有alpha或者rotation這些屬性,但是有get和set方法,其實ObjectAnimator內部的工作機制并不是直接對我們傳入的屬性名進行操作的,而是會去尋找這個屬性名對應的get和set方法。

AnimatorSet

AnimatorSet是用來實現組合動畫的,比如我們要進行一組組合動畫,先進行位移操作,再進行旋轉操作,再進行淡入淡出的操作,代碼如下:

ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);  //位移動畫
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);  //旋轉動畫
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);  //淡入淡出動畫
AnimatorSet animSet = new AnimatorSet();  //新建一個AnimatorSet對象
animSet.play(rotate).with(fadeInOut).after(moveIn);  //AnimatorSet有一個play方法,動畫執行順序
animSet.setDuration(5000);  //動畫持續時間
animSet.start();  //動畫開始
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,237評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,957評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,248評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,356評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,081評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,485評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,534評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,720評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,263評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,025評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,204評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,787評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,461評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,874評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,105評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,945評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,205評論 2 375

推薦閱讀更多精彩內容

  • 1 背景 不能只分析源碼呀,分析的同時也要整理歸納基礎知識,剛好有人微博私信讓全面說說Android的動畫,所以今...
    未聞椛洺閱讀 2,735評論 0 10
  • 3.0以前,android支持兩種動畫模式,tween animation,frame animation,在an...
    Ten_Minutes閱讀 1,664評論 0 4
  • 參考于:http://blog.csdn.net/guolin_blog/article/details/4353...
    墨染書閱讀 2,934評論 0 2
  • 哪有什么武林秘籍 今天分享的書是《一學就會的超級記憶術》,一看到標題,就讓我想起了上學時的武功秘籍。 我上四五年級...
    讓dream照進現實閱讀 300評論 0 0
  • 和老媽談及她們那個年代的婚姻,老媽說,其實那時候的許多人,也是因為到了年紀,覺得結婚是該完成的一項任務,然后經人介...
    一蓑煙雨_886閱讀 95評論 0 0