Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 《Andorid開發藝術探索第七章》-動畫

《Andorid開發藝術探索第七章》-動畫

編輯:關於Android編程

Android動畫深入分析

Android動畫可以分為三種:View動畫、幀動畫和屬性動畫

View動畫

Heading 名稱 標簽 子類 效果 平移動畫 TranslateAnimation 移動View 縮放動畫 ScaleAnimation 放大或縮小View 旋轉動畫 RotaAnimation 旋轉View 透明度動畫 AlphaAnimation 改變VIew的透明度

2. android:interpolator:表示動畫集合所采用的插值器,插值器影響動畫的速度,比如非勻速動畫就需要通過插值器來控制動畫的播放過程。默認為@android:anim/accelerate_decelerate_interpolator即加減速插值器
android:shareInterpolator表示集合中的動畫是否和集合共享同一個插值器。
3. 自定義動畫的時候只需要繼承Animation這個抽象類,然後重寫它的initialize和applyTransformation方法,在initialize方法中做一些初始化工作,在applyTransformation中進行相應的矩陣變化即可。
4. 幀動畫:使用比較簡單,但是使用比較容易引起OOM,所以在使用幀動畫時應盡量避免使用過大的圖片。

View動畫的特殊使用場景

LayoutAnimation作用於VIewGroup,為VIewGroup指定一個動畫
給VIewGroup的子元素加上出場效果


android:delay表示子元素開始動畫的時間延遲,比如子元素入場動畫的時間周期為300ms,那麼0.5表示每個子元素都需要延遲150ms才能入場。
android:animationOrder有三種選項:normal/reverse和random,其中normal表示順序顯示,reverse表示你想顯示,random表示隨機播放入場動畫

 ListView listView = (ListView)findViewById(R.id.list);
 Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item);
LayoutAnimationController controller = new LayoutAnimationController(animation);
 controller.setDelay(0.5f);
 controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
 listView.setLayoutAnimation(controller);
切換動畫主要用到overridePendingTransition(int enterAnim, int exitAnim)這個方法,必須在startActivity(Intent)或者finish()之後被調用才能生效

屬性動畫

屬性動畫中有ValueAnimator、ObjectAnimator和AnimatorSet

1.屬性動畫可以對任意對象的屬性進行動畫而不僅僅是VIew,動畫默認時間間隔為300ms,默認幀率10ms/幀.
2.其中ObjectAnimator繼承自ValueAnimator,AnimatourSet是動畫集合。Nineoldandroids對屬性動畫做了兼容,在API以前的版本其內部是通過代理VIew動畫來實現的。
3.

  //加載屬性動畫需要用到AnimatorInflater類
ObjectAnimator oa = (ObjectAnimator) AnimatorInflater.loadAnimator(MainActivity.this, R.animator.objectdemo);
//用於動畫計算的需要,如果開始和結束的值不是基本類型的時候,這個方法是需要的。
 oa.setEvaluator(new ArgbEvaluator());
 //設置動畫的設置目標
 oa.setTarget(imageView);
 oa.start();

4.
屬性動畫需要定義在res/animator目錄下,它的語法如下;



插值器和估值器
TimeInterpolator為時間插值器,作用為根據時間流逝的百分比來計算當前屬性值改變的百分比。LinearInterpolator表示勻速動畫
TypeEvaluator為類型估值算法。作用是根據當前屬性改變的百分比來計算改變後的屬性值。
屬性動畫要求對象的該屬性有set方法和get方法
自定義插值器需要實現Inter或者TimeInterpolator,自定義估值器需要實現TypeEvaluator

FloatEvaluator的代碼實現

public class FloatEvaluator implements TypeEvaluator {  
        public Object evaluate(float fraction, Object startValue, Object endValue) {  
            float startFloat = ((Number) startValue).floatValue();  
            return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);  
        }  
    }  
AnimtorUpdateListener
    public static interface AnimatorListenre{
    //開始
        void onAinmationStrart(Animatior animator);
        //結束
        void onAinmationEnd(Animatior animator);
        //取消
        void onAinmationCancel(Animatior animator);
        //重復播放
        void onAInmarionRepeat(Animatior animation)
}
public static interface AnimatorUpdateListener{
    void onAnimationUpdate(ValueAnimator animation);
}

監聽整個動畫過程,動畫是由許多幀組成的,每播放一幀,OnAnimationUpdate就會被調用一次。
7. 對Object的屬性abc做動畫,如果想讓動畫生效,要同時滿足兩個條件:
(1) object必須要提供setAbc方法,如果動畫的時候沒有傳遞初始值,那麼還要提供getAbc方法,因為系統要去取abc屬性的初始值
(2) object的setAbc對屬性abc所做的改變必須能夠通過某種方法反映出來,比如會帶來UI的改變之類的。

在對Button的width屬性做動畫沒有效果,是因為他是繼承了TextView,所以有了setWidth方法。
3種解決辦法

給對象加上get和set方法,如果有權限的話,(要在Android SDk內部實現)

用一個類來包裝原始對象,間接為其提供get和set方法

private void perfornAnimate(){
    ViewWrapper wrapper = new ViewWrapper(mBuutton);
    ObjectAnimator.ofInt(wrapper, "width", 500).setDuration(5000).start();
}

private static class ViewWrapper{
    private View mTarget;

    public ViewWrapper(View target){
        mTarget = target;
    }

    public int getWidth(){
        return mTarget.getLayoutParams().width;
    }

    public void setWidth(int width){
        mTarget.getLayoutParams().width = width;
        mTarget.requestLayout();
    }
}

caiyongValueAnimator,監聽動畫過程,自己實現屬性的改變

8.屬性動畫原理

要求動畫作用的對象提供該屬性的set方法,屬性動畫根據你傳遞的該屬性的初始值和最終值,以動畫的效果多次去調用set方法,每次傳遞給set方法的值都不一樣,確切來說是隨著時間的推移,所傳遞的值越來越接近最終值。

屬性動畫需要運行Looper的線程中,set和get方法在內部中都是通過反射來調用的

注意事項

View動畫是對View影象做動畫,並不是真正的改變View的狀態,因此有時候會出現動畫完成後VIew無法隱藏的現象,即setVIsibility(View.GONE)失效,這個時候只要調用view.clearAnimation()清除View動畫即可解決此問題。 不要使用px,盡量使用dp 在3.0開始,屬性動畫的單擊事件觸發位置為移動的位置,但是VIew動畫仍然砸原位置。

組合動畫

實現組合動畫功能主要需要借助AnimatorSet這個類,這個類提供了一個play()方法,如果我們向這個方法中傳入一個Animator對象(ValueAnimator或ObjectAnimator)將會返回一個AnimatorSet.Builder的實例,AnimatorSet.Builder中包括以下四個方法:

after(Animator anim)   將現有動畫插入到傳入的動畫之後執行
after(long delay)   將現有動畫延遲指定毫秒後執行
before(Animator anim)   將現有動畫插入到傳入的動畫之前執行
with(Animator anim)   將現有動畫和傳入的動畫同時執行

我們想要讓TextView先從屏幕外移動進屏幕,然後開始旋轉360度,旋轉的同時進行淡入淡出操作

    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();  
    animSet.play(rotate).with(fadeInOut).after(moveIn);  
    animSet.setDuration(5000);  
    animSet.start();  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved