Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android動畫

Android動畫

編輯:關於Android編程

首先分清幾大類: 三大類

一. Drawable Animation (or Frame Animation)—即幀(逐幀)動畫

二. View Animation (or Tween Animation)—即補間(視圖)動畫

三. Property Animation—即屬性動畫


然後了解來龍去脈

前兩種動畫是API 3.0以前就有, API 3.0之後新加入了Property動畫

如果你想在3.0以前的機器上使用同樣效果, 可以使用NineOldAndroids動畫庫.

當然記住, 凡是前兩種動畫可以實現的動畫, 屬性動畫一定可以實現其效果.

幀動畫很簡單, 一幀一幀的, 可以使用XML文件把資源組合起來

補間動畫使用很常見, 補間補間, 就是把起止幀之間的幀畫出來,改變View的透明度,位置,大小,角度. 注意位置不是真實的改變(不是真實傷害,哈哈),只是繪制位置的改變.

屬性動畫, 會改變View的真實屬性, 500多行的抽象基類Animator基本不直接使用, 最常用的是子類ValueAnimator和ObjectAnimator.


最後具體操作

一. 幀動畫的介紹:

1)特點: 細膩靈活,但是增加了資源制作負擔而且文件量大

2)使用步驟:
a.添加幀: XML定義資源文件,或者Java代碼創建
b.引用支持類:AnimationDrawable

1>XML方式:在/res/drawable下新建:



      
      
      
      
  


//後續所用代碼
frameAnim =(AnimationDrawable)getResources().getDrawable(id);
view.setBackgroundDrawable(frameAnim);
frameAnim.start();frameAnim.stop();
2>Java代碼方式:

frameAnim =new AnimationDrawable();
frameAnim.addFrame(getResources().getDrawable(R.drawable.img0), 50);
frameAnim.addFrame(getResources().getDrawable(R.drawable.img1), 100);
frameAnim.setOneShot(false);view.setBackgroundDrawable(frameAnim);
frameAnim.start();
frameAnim.stop();

二. 補間動畫

1)特點: 過渡自然, 實現起來簡單快速.順便說下實現的方式是給出兩個關鍵幀,通過一些算法將給定屬性值在給定的時間內在兩個關鍵幀間漸變。
2)使用步驟:
a. 設置動畫形式: 如漸變
b. 設定起止狀態: 如起始1.0f和結束0.1f

1> XML方式
XML文件的根元素可以 為,,,,,(表示以上幾個動畫的集合,set可以嵌套).默認情況下,所有動畫是同時進行的,可以通過startOffset屬性設置 各個動畫的開始偏移(開始時間)來達到動畫順序播放的效果.
  

//漸變形式,起始狀態1.0結束狀態0.1
anim =AnimationUtils.loadAnimation(this, R.anim.alpha_anim);
view.startAnimation(anim);
2>Java代碼方式:

Animation anim = new AlphaAnimation(1.0f,0.1f);
//設置持續時間
anim.setDuration(2000);
//清除原有的動畫,避免多次點擊出現重復的效果
view.clearAnimation();
//開始執行動畫
view.startAnimation(anim);

5種封裝類:
AlphaAnimation:透明度(alpha)漸變效果,對應標簽。

TranslateAnimation:位移漸變,需要指定移動點的開始和結束坐標,對應標簽。

ScaleAnimation:縮放漸變,可以指定縮放的參考點,對應標簽。

RotateAnimation:旋轉漸變,可以指定旋轉的參考點,對應標簽。

AnimationSet:組合漸變,支持組合多種漸變效果,對應標簽。

三. 屬性動畫

1)特點: 更廣泛(比如可以將view的背景顏色屬性改變), 實現起來費腦.
2)使用步驟:
a.
b.
ValueAnimator表示一個動畫,包含動畫的開始值,結束值,持續時間等屬性。
ValueAnimator內部流程:
1.計算屬性值;

時間因子(input) = 動畫已進行的時間跟動畫總時間(duration)的比計算(0~1)—TimeInterpolator
插值因子(fraction,表示動畫的完成度) = TimeInterpolator通過開始值,結束值,時間因子計算出—TimeInterpolator
公式為: fraction = (Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
屬性值 = TypeAnimator通過插值因子計算出 = {開始值,結束值,差值}—TypeAnimator
根據TypeEvaluator的函數evaluate():
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}

2.根據屬性值執行相應的動作,如改變對象的某一屬性。

需要實現ValueAnimator.onUpdateListener接 口,這個接口只有一個函數onAnimationUpdate(),
在這個函數中會傳入ValueAnimator對象做為參數,通過這個 ValueAnimator對象的getAnimatedValue()函數可以得到當前的屬性值
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener( AnimatorUpdateListener() {
@Override
onAnimationUpdate(ValueAnimator animation) {
Log.i(“update”, ((Float) animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator( CycleInterpolator(3));
animation.start();

ObjectAnimator繼承自ValueAnimator, 屬性動畫一般使用這個類,但需滿足以下條件,否則就選用ValueAnimator
這也是兩者的區別:
1.對象(View類等)應該有一個setter函數:set(駝峰命名法)
2.如上面的例子中,像ofFloat之類的工場方法,第一個參數為對象名,第二個為屬性名,後面的參數為
可變參數,如果values…參數只設置了一個值的話,那麼會假定為目的值,屬性值的變化范圍為當前值到目的值,為了獲得當前值,
該對象要有相應屬性的getter方法:get(駝峰命名法)
3.如果有getter方法,其應返回值類型應與相應的setter方法的參數類型一致。
ObjectAnimator內部流程同ValueAnimator.
根據應用動畫的對象或屬性的不同,可能需要在onAnimationUpdate函數中調用invalidate()函數刷新視圖。
說明:請求重繪View樹,即draw()過程,假如視圖發生大小沒有變化就不會調用layout()過程,並且只繪制那些“需要重繪的”
視圖,即誰(View的話,只繪制該View ;ViewGroup,則繪制整個ViewGroup)請求invalidate()方法,就繪制該視圖。
AnimationSet提供了一個把多個動畫組合成一個組合的機制,並可設置組中動畫的時序關系,如同時播放,順序播放等。
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(anim1).before(anim2);
bouncer.play(anim2).with(anim3);
bouncer.play(anim2).with(anim4)
bouncer.play(anim5).after(amin2);
animatorSet.start();

屬性動畫還有個類—LayoutTransition
容器布局動畫就是當一個布局容器中的view方式改變時所產生的動畫,
比如:但一個相對布局中新增加一個view時或者刪除一個view時(或者visible改變時),那麼就可以通過一個動畫來進行表現。
有這四種容器動畫:
1、APPEARING: 動畫所運行的項目出現在這個容器中時,即:view顯示時的動畫
2、CHANGE_APPEARING: 由於在這個容器總新增加了一個view,而導致原來的view位置發生改變所以會觸發這個動畫。
3、DISAPPEARING: view在這個容器中消失時觸發的動畫
4、CHANGE_DISAPPEARING: 由於在這個容器中移除了一個view,而導致原來的view位置發生改變所以會觸發這個動畫。
使用步驟:
1、創建LayoutTransition對象mTransitioner
2、創建動畫
3、在xml文件中將相應布局的屬性Android:animateLayoutChanges=”true”設置為true
4、將動畫通過mTransitioner的setAnimator方法設置給mTransitioner
5、通過布局控件的setLayoutTransition方法將mTransitioner設置進去
mButtonAddBtn = (Button) findViewById(R.id.buttonLayoutAnmation);
mLayout = (LinearLayout) findViewById(R.id.layoutanmation);

    LayoutTransition transition = new LayoutTransition();//創建LayoutTransition對象
    transition.getDuration(2000);
    transition.setAnimator(LayoutTransition.APPEARING, AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.animator));//創建動畫
    transition.setAnimator(LayoutTransition.CHANGE_APPEARING, null);
    transition.setAnimator(LayoutTransition.DISAPPEARING, null);
    transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,null);
    mLayout.setLayoutTransition(transition);//方法將mTransitioner設置給布局

    mButtonAddBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            count++;
            Button btn = new Button(ActivityLayoutAnimations.this);//1.建立button對象
            //2.設置LayoutParams,寬和高
            ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            btn.setLayoutParams(params);//3.將寬高加到button上
            btn.setText("按鈕" + count);
            mLayout.addView(btn);//4.將button加到布局中

        }
    });

屬性動畫的高級用法中最有技術含量的也就是如何編寫出一個合適的TypeEvaluator

View繪制流程:
大小->位置->繪制
onMeasure()->onLayout()->onDraw()
整個View樹的繪圖流程在ViewRoot.java類的performTraversals()函數展開,該函數所做 的工作可簡單概況為是否需要重新計算視圖大小(measure)、是否需要重新安置視圖的位置(layout)、以及是否需要重繪(draw)

 

Android_View_View繪制流程

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved