Android動畫初探

安卓動畫目前共分為三種動畫逐幀動畫、補間動畫和屬性動畫。

一、逐幀動畫(frame-by-frame animation)

逐幀動畫就是將一個完整的動畫拆分成一張張單獨的圖片,然后再將它們連貫起來進行播放,類似于動畫片的工作原理。

  • 素材圖片放到drawable文件夾下,mipmap下無法引用
素材圖片
  • 在drawable文件夾下新建wifi-z的xml文件用來存放圖片
    <?xml version="1.0" encoding="utf-8"?>
    <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    //oneshot表示是否循環播放 true只播放一次,false循環播放,圖片順序不能變否則動畫不連貫
    <item
    android:drawable="@drawable/icon_5"
    android:duration="300" />
    <item
    android:drawable="@drawable/icon_4"
    android:duration="300" />
    <item
    android:drawable="@drawable/icon_3"
    android:duration="300" />
    <item
    android:drawable="@drawable/icon_2"
    android:duration="300" />
    <item
    android:drawable="@drawable/icon_1"
    android:duration="300" />
    <item
    android:drawable="@drawable/icon_0"
    android:duration="300" />
    </animation-list>

  • Activity中引用動畫
    // 存放動畫圖片的imageview
    private ImageView mImg;
    // 開啟動畫的按鈕
    private Button mBtn;
    // 實現逐幀動畫的類
    private AnimationDrawable animationDrawable;

        mBtn.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              mImg.setImageResource(R.drawable.wifi_d);
              animationDrawable = (AnimationDrawable) mImg.getDrawable();
              animationDrawable.start();//停止調用stop方法
          }
      });
    

二、補間動畫(tweened animation)

補間動畫則是可以對View進行一系列的動畫操作,包括淡入淡出、縮放、平移、旋轉四種。
<b>
補間動畫只是表面上的View移動,View實際還在原來位置,而屬性動畫則是View也跟著移動</b>

  • 淡入淡出
    AlphaAnimation:透明度(alpha)漸變效果,對應<alpha/>標簽。
    外部xml方法
    <alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromAlpha="1.0"
    android:fillAfter="false"http://動畫結束時是否保持在該位置
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"http://插值器
    android:toAlpha="0.1" />

      Animation animation = AnimationUtils.loadAnimation(this, R.anim.alpha);
      mImg.startAnimation(animation);
    

    java方式
    Animation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
    alphaAnimation.setDuration(2000);
    alphaAnimation.setFillAfter(false);
    mImg.startAnimation(alphaAnimation);

  • 縮放
    ScaleAnimation:縮放漸變,可以指定縮放的參考點,對應<scale/>標簽。
    xml方式
    <scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXScale="0.2"
    android:fromYScale="0.2"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%" //動畫起始位置,相對于屏幕的百分比,兩個都為50%表示動畫從自身中間開始
    android:toXScale="1.5"
    android:toYScale="1.5" />
    java方式
    Animation scaleAnimation = new ScaleAnimation(0.0f, 1.5f, 0.0f, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    scaleAnimation.setDuration(2000);//設置動畫持續時間為500毫
    scaleAnimation.setInterpolator(this, android.R.anim.accelerate_interpolator);//設置動畫插入器
    mImg.startAnimation(scaleAnimation);

  • 平移
    TranslateAnimation:位移漸變,需要指定移動點的開始和結束坐標,對應<translate/>標簽。
    xml方式
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXDelta="0"
    android:fromYDelta="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:toXDelta="320"
    android:toYDelta="0" />
    java方式
    Animation translateAnimation = new TranslateAnimation(0, 320, 0, 0);
    translateAnimation.setDuration(2000);
    translateAnimation.setInterpolator(this, android.R.accelerate_decelerate_interpolator);//設置動畫插入器
    mImg.startAnimation(translateAnimation);

  • 旋轉
    RotateAnimation:旋轉漸變,可以指定旋轉的參考點,對應<rotate/>標簽。
    xml方式
    <rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromDegrees="0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatCount="-1"http://-1代表無限循環 正數代表循環幾次
    android:repeatMode="reverse"http://動畫重復的模式,reverse為反向,當第偶次執行時,動畫方向會相反。restart為重新執行,方向不變
    android:toDegrees="360" />
    java方式
    Animation rotateAnimation = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    rotateAnimation.setDuration(1000);
    rotateAnimation.setInterpolator(this, android.R.anim.accelerate_decelerate_interpolator);//設置動畫插入器
    mImg.startAnimation(rotateAnimation);

  • 組合
    AnimationSet:組合漸變,支持組合多種漸變效果,對應<set/>標簽。
    java方式
    AnimationSet animationSet = new AnimationSet(true);
    animationSet.addAnimation(alphaAnimation);
    animationSet.addAnimation(scaleAnimation);
    mImg.startAnimation(animationSet);

  • 動畫監聽器
    alphaAnimation.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
    //動畫開始時調用 }
    @Override
    public void onAnimationEnd(Animation animation) {
    //動畫結束時調用 }
    @Override
    public void onAnimationRepeat(Animation animation) {
    //動畫重復時調用 } });

  • 插值器
    AccelerateInterpolator 加速,開始時慢中間加速
    DecelerateInterpolator 減速,開始時快然后減速
    AccelerateDecelerateInterolator 先加速后減速,開始結束時慢,中間加速
    AnticipateInterpolator 反向,先向相反方向改變一段再加速播放
    AnticipateOvershootInterpolator 反向加超越,先向相反方向改變,再加速播放,會超出目的值然后緩慢移動至目的值
    BounceInterpolator 跳躍,快到目的值時值會跳躍,如目的值100,后面的值可能依次為85,77,70,80,90,100
    CycleIinterpolator 循環,動畫循環一定次數,值的改變為一正弦函數:Math.sin(2* mCycles* Math.PI* input)
    LinearInterpolator 線性,線性均勻改變
    OvershootInterpolator超越,最后超出目的值然后緩慢改變到目的值

三、屬性動畫(property animation)

功能很強大,可以替代逐幀動畫與補間動畫。

  • ValueAnimator
    屬性動畫的運行機制是通過不斷地對值進行操作來實現的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內部使用一種時間循環的機制來計算值與值之間的動畫過渡,我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。

      //從0-1-5-1 float 類型 整型可以ofInt
      ValueAnimator animator = ValueAnimator.ofFloat(0f, 1.0f, 5.0f, 1.0f);
      animator.setDuration(300);
      animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
          @Override
          public void onAnimationUpdate(ValueAnimator valueAnimator) {
              float value = (float) valueAnimator.getAnimatedValue();
              Log.d(TAG, "onAnimationUpdate: " + value);
          }
      });
      animator.start();
    
  • ObjectAnimator
    可以直接對任意對象的任意屬性進行動畫操作的,比如說View的alpha屬性。
    // 旋轉:rotation 漸變:alpha 平移:x軸tarnslationX(平移時需要先獲取當前位置,getTranslationX)
    //縮放 scaleX/scaleY
    ObjectAnimator animator = ObjectAnimator.ofFloat(mProperty, "alpha", 1.f, 0f);
    animator.setDuration(1000);
    animator.start();

  • AnimatorSet(組合動畫)

  • after(Animator anim) 將現有動畫插入到傳入的動畫之后執行

  • after(long delay) 將現有動畫延遲指定毫秒后執行

  • before(Animator anim) 將現有動畫插入到傳入的動畫之前執行

  • with(Animator anim) 將現有動畫和傳入的動畫同時執行
    ObjectAnimator translate = ObjectAnimator.ofFloat(mProperty, "translationX", -500f, 0f);
    ObjectAnimator rotation = ObjectAnimator.ofFloat(mProperty, "rotation", 0f, 360f);
    ObjectAnimator scale = ObjectAnimator.ofFloat(mProperty, "scaleX", 1.0f, 2.0f, 1.0f);
    AnimatorSet set = new AnimatorSet();
    set.play(rotation).with(scale).after(translate);
    set.setDuration(5000);
    set.start();

  • Animator監聽器

  • 監聽所有方法
    translate.addListener(new Animator.AnimatorListener() {
    @Override
    public void onAnimationStart(Animator animator) {

         }
    
         @Override
         public void onAnimationEnd(Animator animator) {
    
         }
    
         @Override
         public void onAnimationCancel(Animator animator) {
    
         }
    
         @Override
         public void onAnimationRepeat(Animator animator) {
    
         }
     });
    
  • 監聽單個方法
    rotation.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
    super.onAnimationEnd(animation);
    }
    });

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

推薦閱讀更多精彩內容

  • Animation Animation類是所有動畫(scale、alpha、translate、rotate)的基...
    四月一號閱讀 1,933評論 0 10
  • 1 背景 不能只分析源碼呀,分析的同時也要整理歸納基礎知識,剛好有人微博私信讓全面說說Android的動畫,所以今...
    未聞椛洺閱讀 2,735評論 0 10
  • Android中動畫分為三種: 逐幀動畫 補間動畫 屬性動畫 逐幀動畫 逐幀動畫類似于gif或是電影的原理,通過將...
    fengmlo閱讀 724評論 0 2
  • 本文參加#未完待續,就要表白#活動,本人承諾,文章內容為原創,且未在其他平臺發表過。 入我相思門,知我相思苦, 長...
    唇寒閱讀 305評論 1 5
  • 上次寫的文章里面提到了我的女兒,有朋友驚呼「你竟然已經有孩子了!」這時候我才想起來,我經常在網上交流的朋友們,大都...
    c5de959d631b閱讀 938評論 8 6