溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android全套動畫使用的技巧是什么

發(fā)布時間:2021-11-26 15:51:41 來源:億速云 閱讀:143 作者:柒染 欄目:移動開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)Android全套動畫使用的技巧是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

 一、Android View 動畫框架

Animation框架定義了透明度、旋轉(zhuǎn)、縮放和位移幾種常見的動畫,控制的整個View,實現(xiàn)原理是每次繪制視圖時View所在ViewGroup中的drawChild函數(shù)獲取該View的Animation的Transformation值,然后調(diào)用canvas.concat(transformToApply.getMatrix()),通過矩陣運(yùn)算完成動畫幀。如果沒有完成就繼續(xù)調(diào)用invalidate()函數(shù),啟動下次繪制來驅(qū)動動畫,從而完成整個動畫的繪制。

視圖動畫使用簡單,效果豐富,它提供了AlphaAnimation、RotateAnimation、TranslateAnimation、ScaleAnimation四種動畫方式,并提供動畫集合AnimationSet,混合使用多種動畫。在Android3.0之前,視圖動畫一家獨大,但隨著Android3.0之后屬性動畫框架的推出,它的風(fēng)光就大不如從前。相比屬性動畫,視圖動畫的一個非常大的缺陷就是不具備交互性,當(dāng)某個元素發(fā)生視圖動畫后,其響應(yīng)事件的位置還依然在動畫前的地方,所以視圖動畫只能做普通的動畫效果,避免交互的發(fā)生。但是它的優(yōu)點也非常明顯,即效率比較高且使用方便。

視圖動畫使用非常簡單,不僅可以通過XML文件來描述一個動畫過程,同樣也可以使用代碼來控制整個動畫過程。

(1)、透明度動畫

為視圖增加透明度的變換動畫。

AlphaAnimation aa = new AlphaAnimation(0, 1);  aa.setDuration(1000);  view.startAnimation(aa);

(2)、旋轉(zhuǎn)動畫

為視圖增加旋轉(zhuǎn)的變換動畫。

RotateAnimation ra = new RotateAnimation(0, 360, 100, 100);  ra.setDuration(1000);  view.startAnimation(ra);

其參數(shù)分別為旋轉(zhuǎn)的起始角度和旋轉(zhuǎn)中心點的坐標(biāo),當(dāng)然,可以通過設(shè)置參數(shù)來控制旋轉(zhuǎn)動畫的參考系,這里設(shè)置旋轉(zhuǎn)動畫的參考系為中心。

RotateAnimation ra1 = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5F, RotateAnimation.RELATIVE_TO_SELF, 0.5F);

(3)、位移動畫

為視圖移動時增加位移動畫。

TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 300);  ta.setDuration(1000);  view.startAnimation(ta);

(4)、縮放動畫

為視圖的縮放增加動畫效果

ScaleAnimation sa = new ScaleAnimation(0, 2, 0, 2);  sa.setDuration(1000);  view.startAnimation(sa);

與旋轉(zhuǎn)動畫一樣,縮放動畫也可以設(shè)置羅芳的中心點,設(shè)置中心為自身中心效果

ScaleAnimation sa1 = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5F, Animation.RELATIVE_TO_SELF, 0.5F);  sa1.setDuration(1000);  view.startAnimation(sa1);

(5)、動畫集合

通過AnimationSet,可以將動畫以組合的形式展現(xiàn)出來:

AnimationSet as = new AnimationSet(true);  as.setDuration(1000);  AlphaAnimation aa = new AlphaAnimation(0, 1);  aa.setDuration(1000);  as.addAnimation(aa);  RotateAnimation ra = new RotateAnimation(0, 360, 100, 100);  ra.setDuration(1000);  as.addAnimation(ra);  TranslateAnimation ta = new TranslateAnimation(0, 200, 0, 300);  ta.setDuration(1000);  as.addAnimation(ta);  ScaleAnimation sa = new ScaleAnimation(0, 2, 0, 2);  sa.setDuration(1000);  as.addAnimation(sa);  view.startAnimation(as);

可以直接拷貝運(yùn)行代碼看效果!

對于動畫事件,Android也提供了對應(yīng)的監(jiān)聽回調(diào),代碼:

as.setAnimationListener(new Animation.AnimationListener() {  @Override  public void onAnimationStart(Animation animation) {  //動畫開始  }  @Override  public void onAnimationEnd(Animation animation) {  //動畫結(jié)束  }  @Override  public void onAnimationRepeat(Animation animation) {  //動畫重復(fù)  }  });

二、屬性動畫

由于Android3.0之前已有的動畫框架Animation存在一些局限性——動畫改變的只是顯示,并不能響應(yīng)事件。因此在Android3.0之后,Google就提出了屬性動畫這樣一個新的動畫框架,實現(xiàn)更豐富的效果。

而在Animator框架中使用最多的就是AnimatorSet和ObjectAnimator配合,使用ObjectAnimator進(jìn)行更精細(xì)化控制,只控制一個對象的一個屬性值,而使用多個ObjectAnimator組合到AnimatorSet形成一個動畫。而且ObjectAnimator能夠自動驅(qū)動,可以調(diào)用setFrameDelay(long  frameDelay)設(shè)置動畫幀之間的間隙時間。最重要的是,屬性動畫通過調(diào)用屬性的get、set方法來真實地控制了一個View的屬性值,因此強(qiáng)大的屬性動畫框架,基本可以實現(xiàn)所有的動畫效果。

(1)、ObjectAnimator

ObjectAnimator是屬性動畫框架中最重要的實行類,創(chuàng)建一個ObjectAnimator只需要通過他的靜態(tài)工廠類直接返回一個ObjectAnimator對象。參數(shù)包括一個對象和對象的屬性名字,但這個屬性也必須有g(shù)et和set函數(shù),內(nèi)部會通過Java反射機(jī)制來調(diào)用set函數(shù)修改對象屬性值。同樣,你也可以調(diào)用setInterpolator設(shè)置相應(yīng)的差值器。

接下來試想一下對一個Button添加一個平移動畫,使用以前的動畫框架平移后將不能觸發(fā)點擊事件,點擊的有效區(qū)域仍然是原來的地方,點擊移動后的地方是不會有點擊事件發(fā)生的。而屬性動畫則不同,它真實地改變了一個View的屬性,所以事件響應(yīng)的區(qū)域也同樣發(fā)生了改變,這時候點擊移動后的按鈕,就會響應(yīng)點擊事件了。

屬性動畫平移代碼如下:

ObjectAnimator animator = ObjectAnimator.ofFloat(  imageView,  "translationX",  200F);  animator.setDuration(300);  animator.start();

在使用ObjectAnimator的時候,有一點非常重要,那就是要操縱的屬性必須具有g(shù)et、set方法,不然ObjectAnimator就無法生效。下面是常用的屬性:

  • translationX和translationY:這兩個屬性作為一種增量控制著View對象從它布局容器左上角坐標(biāo)開始的位置。

  • rotation、rotationX和rotationY:這個三個屬性控制View對象圍繞支點進(jìn)行2D和3D旋轉(zhuǎn)。

  • scaleX和scaleY:這兩個屬性控制著View對象圍繞他的支點進(jìn)行2D縮放。

  • pivotX和pivotY:這兩個屬性控制著View對象的支點位置,圍繞這個支點進(jìn)行旋轉(zhuǎn)和縮放變換處理。默認(rèn)情況下,該支點的位置就是View對象的中心點。

  • x和y:這兩個簡單實用的屬性,描述了View對象在它的容器中的最終位置,它是最初的左上角坐標(biāo)和translationX、translationY值的累積和。

  • alpha:表示View對象的alpha透明度。默認(rèn)值是1(不透明),0代表完全透明(不可見)。

根據(jù)以上得知視圖動畫所實現(xiàn)的動畫效果,這里基本都已經(jīng)包含了。

那么如果一個屬性沒有g(shù)et、set方法,屬性動畫是不是就束手無策了呢?答案是否定的,Google在應(yīng)用層提供了兩種方案來解決這個問題,一個是通過自定義一個屬性類或者包裝類,來間接地給這個屬性增加get、set方法;或者通過ValueAnimator來實現(xiàn),ValueAnimator在后面的內(nèi)容中講到,這個先看看使用包裝類的方法給一個屬性增加get、set方法,代碼如下:

private static class WrapperView {     private View mTarget;      public WrapperView(View mTarget) {         this.mTarget = mTarget;     }      public int getWidth() {         return mTarget.getLayoutParams().width;     }      public void setWidth(int width) {         mTarget.getLayoutParams().width = width;         mTarget.requestLayout();     } }

通過以上代碼,就跟一個屬性包裝了一層,并給它提供了get、set方法。使用時只需要操縱包裝類就可以間接調(diào)用到get、set方法了,代碼如下所示:

WrapperView wrapperView = new WrapperView(view);  ObjectAnimator.ofInt(wrapperView, "width", 500).setDuration(5000).start();

(2)、PropertyValuesHolder

類似視圖動畫中的AnimationSet,在屬性動畫中,如果針對同一個對象的多個屬性,要同時作用多種動畫,可以使用PropertyValuesHolder來實現(xiàn)。比如平移動畫,如果在平移的過程中同時改變X、Y軸的縮放,可以這樣實現(xiàn),代碼:

PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("translationX", 300);  PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);  PropertyValuesHolder pvh4 = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);  ObjectAnimator.ofPropertyValuesHolder(pvh2, pvh3, pvh4).setDuration(1000).start();

在代碼中,分別使用PropertyValuesHolder  對象控制translationX、scaleX、scaleY這三個屬性,最屌調(diào)用ObjectAnimator.ofPropertyValuesHolder方法實現(xiàn)多屬性動畫的共同作用,整個實現(xiàn)方法非常類似AnimatorSet使用。

(3)、ValueAnimator

ValueAnimator在屬性動畫中占用非常重要的地位,雖然不ObjectAnimator那樣耀眼,但它卻是屬性動畫的核心所在,ObjectAnimator也是繼承自ValueAnimator。

public final class ObjectAnimator extends ValueAnimator

ValueAnimator本身不提供任何動畫效果,它更像一個數(shù)值發(fā)生器,用來產(chǎn)生具有一定規(guī)律的數(shù)字,從而讓調(diào)用者來控制動畫的實現(xiàn)過程,ValueAnimator的一般使用方法:通常在ValueAnimator的AnimatorUpdateListener中監(jiān)聽數(shù)值的變換,完成動畫的變換。

ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 100);  valueAnimator.setTarget(imageView);  valueAnimator.setDuration(1000).start();  valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {  @Override  public void onAnimationUpdate(ValueAnimator animation) {     Float value = (Float) animation.getAnimatedValue();     }  });

(4)、動畫事件的監(jiān)聽

一個完整的動畫具有Start、Repeat、End、Cancel四個過程,通過Android提供了接口,很方便地監(jiān)聽到這四個事件:

ObjectAnimator anim = ObjectAnimator.ofFloat(imageView, "alpha", 0.5F); anim.addListener(new Animator.AnimatorListener() {     @Override     public void onAnimationStart(Animator animation) {              }      @Override     public void onAnimationEnd(Animator animation) {      }      @Override     public void onAnimationCancel(Animator animation) {      }      @Override     public void onAnimationRepeat(Animator animation) {      } }); anim.start();

大部分的時候只關(guān)心onAnimationEnd事件,所以Android也提供了一個AnimatorListenerAdapter來讓我們選擇必要的事件進(jìn)行監(jiān)聽:

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

(***nimatorSet

對于一個屬性同時作用多個屬性動畫效果,前面已經(jīng)使用PropertyValuesHolder實現(xiàn)了這樣的效果。而AnimatorSet不僅能實現(xiàn)這樣的效果,同時也能實現(xiàn)更為精確的順序控制。同樣是實現(xiàn)上面使用PropertyValuesHolder演示的那個動畫效果,如果使用AnimatorSet來實現(xiàn),那么代碼如下:

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView, "translationX", 300f);  ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(imageView, "scaleX", 1f, 0f, 1f);  ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(imageView, "scaleY", 1f, 0f, 1f);  AnimatorSet animatorSet = new AnimatorSet();  animatorSet.setDuration(1000);  animatorSet.playTogether(objectAnimator, objectAnimator1, objectAnimator2);  animatorSet.start();

在屬性動畫中,AnimatorSet正是通過playTogether()、playSquentially()、animSet.play().width()、defore()、after()這些方法來控制多個動畫的協(xié)同工作方式,從而做到對動畫播放順序的精確控制。

(6)、在XML中使用屬性動畫

屬性動畫同視圖動畫一樣,也可以直接寫在XML文件中,代碼:

<?xml version="1.0" encoding="utf-8"?>  <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"  android:duration="1000"  android:propertyName="scaleX"  android:valueFrom="1.0"  android:valueTo="2.0"  android:valueType="floatType">  </objectAnimator>

前提使用XML定義屬性動畫XML文件一定要放在res/animator/filename.xml文件夾下面才能識別,否則不能識別。發(fā)現(xiàn)屬性動畫與視圖動畫在XML文件中的寫法很相似。在程序中使用:

Animator anim = AnimatorInflater.loadAnimator(this,R.animator.filename);  anim.setTarget(view);  anim.start();

(7)、View的animate方法

在Android3.0之后,Google給View增加了animate方法來直接驅(qū)動屬性動畫,代碼如下:

imageView.animate()         .alpha(0)         .y(300)         .setDuration(300)         .withStartAction(new Runnable() {             @Override             public void run() {              }         })         .withEndAction(new Runnable() {             @Override             public void run() {                 runOnUiThread(new Runnable() {                     @Override                     public void run() {                                              }                 });             }         }).start();

三、Android布局動畫

布局動畫是指作用在ViewGroup上,給ViewGroup增加View時添加一個動畫過渡效果。最簡單的布局動畫是在ViewGroup的XML中,使用如下代碼打開布局動畫:

android:animateLayoutChanges="true"

通過以上設(shè)置,當(dāng)ViewGroup添加到View時,子View會呈現(xiàn)逐漸顯示的過渡效果,不過這個效果是Android默認(rèn)的顯示的過渡效果,無法使用自定義動畫來替換這個效果。

還可以通過使用LayoutAnimatorController類自定義一個子View的過渡效果,添加一個視圖動畫,使得子View出現(xiàn)的時候有一個縮放的動畫效果,代碼:

LinearLayout ll = (LinearLayout) findViewById(R.id.ll); ScaleAnimation sa = new ScaleAnimation(0, 1, 0, 1); sa.setDuration(2000); //設(shè)置布局動畫的顯示 LayoutAnimationController lac = new LayoutAnimationController(sa, 0.5f); //設(shè)置布局動畫 ll.setLayoutAnimation(lac);

LayoutAnimationController  的***個參數(shù),是需要作用的動畫,而第二個參數(shù),則是每個子View顯示的delay時間。當(dāng)delay時間不為0時,可以設(shè)置子View顯示的順序。

//順序  public static final int ORDER_NORMAL = 0;  //隨機(jī)  public static final int ORDER_REVERSE = 1;  //反序  public static final int ORDER_RANDOM = 2;

四、Interpolators&mdash;&mdash;插值器

插值器是動畫一個非常重要的概念,通過插值器Interpolators,可以定義動畫變換速率,這一點非常類似物理中的加速度,起作用主要是控制目標(biāo)變量的變化值進(jìn)行對應(yīng)的變化。

  • AccelerateDecelerateInterpolator 在動畫開始與介紹的地方速率改變比較慢,在中間的時候加速

  • AccelerateInterpolator 在動畫開始的地方速率改變比較慢,然后開始加速

  • AnticipateInterpolator 開始的時候向后然后向前甩

  • AnticipateOvershootInterpolator 開始的時候向后然后向前甩一定值后返回***的值

  • BounceInterpolator 動畫結(jié)束的時候彈起

  • CycleInterpolator 動畫循環(huán)播放特定的次數(shù),速率改變沿著正弦曲線

  • DecelerateInterpolator 在動畫開始的地方快然后慢

  • LinearInterpolator 以常量速率改變

  • OvershootInterpolator 向前甩一定值后再回到原來位置

  • PathInterpolator 路徑插值器

關(guān)于Android全套動畫使用的技巧是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI