1. 程式人生 > >Android——動畫學習,介面切換

Android——動畫學習,介面切換

閒扯:
現在好多APP真的是炫酷阿,人家那UI做的漂亮,可是有多動畫是咋實現的呢?今天就學習一下。
之前用的頂多就是做一個動態的dialog。。。沒有審美的人說多了都是淚阿,今天在這虐狗的日子,我就不去電影院買隔著的座了也不去小飯館自己佔著雙人的小桌了,還是踏實的乾點該乾的事吧,進入主題。

動畫效果的實現:

在安卓3.0以前有兩種方法:

  • 幀實現(Frame)
  • 補間動畫(Tweened)
    • alpha —— 漸變透明動畫
    • scale —— 漸變尺寸伸縮
    • transition —— 位置轉移
    • rotate —— 旋轉動畫

安卓3.0以後
新添加了屬性動畫(property animation)

好了,現在一個一個開始學習。

幀實現(Frame)
幀動畫是最容易實現的一種動畫,這種動畫更多的依賴於完善的UI資源,他的原理就是將一張張單獨的圖片連貫的進行播放,
從而在視覺上產生一種動畫的效果;

需要:

  1. 所有動畫的圖片,放在drawable資料夾下;
  2. xml檔案定義AnimationDrawable;
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
>
<item android:drawable="@drawable/a_0" android:duration="100" /> <item android:drawable="@drawable/a_1" android:duration="100" /> <item android:drawable="@drawable/a_2" android:duration="100" /> </animation-list>
  1. Java啟動動畫,將Drawable作為View的北京並通過Drawable來播放動畫;
protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_frame_animation);
        ImageView animationImg1 = (ImageView) findViewById(R.id.animation1);
        **animationImg1.setImageResource(R.drawable.frame_anim1);
        AnimationDrawable animationDrawable1 = (AnimationDrawable) animationImg1.getDrawable();
        animationDrawable1.start();**
    }

注:

  1. android:oneshot=”false” ,這個oneshot 的含義就是動畫執行一次(true)還是迴圈執行多次。
  2. 幀動畫使用比較簡單,但是比較容易引起OOM,所有使用幀動畫的時候應儘量避免使用過多尺寸較大的圖片。

之前一直用的。。。只是入門級的。。。

補間動畫
補間動畫又可以分為四種形式,分別是:

  • alpha(淡入淡出)
  • translate(位移)
  • scale(縮放大小)
  • rotate(旋轉)

實現:

  1. xml檔案——程式碼會更容易書寫和閱讀,同時也更容易複用。建議採用xml來定義動畫,因為xml格式的動畫 可讀性更好。
  2. 可以是單個動畫,也可以由一系列的動畫組成。
  3. 通過Animation的setAnimationListener方法可以給View動畫新增過程監聽。

實現流程:
①在res/anim/ 資料夾下定義動畫實現方式;

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 漸變透明度動畫效果 -->
    <!--
        透明度控制動畫效果 alpha
            浮點型值:
            fromAlpha 屬性為動畫起始時透明度
            toAlpha   屬性為動畫結束時透明度
                說明: 
                0.0表示完全透明
                1.0表示完全不透明
                以上值取0.0-1.0之間的float資料型別的數字
         長整型值:
            duration  屬性為動畫持續時間
              說明:     
                  時間以毫秒為單位
    -->
    <alpha
        android:duration="5000"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />

    <!-- 漸變尺寸伸縮動畫效果 -->
    <!--
         尺寸伸縮動畫效果 scale
         屬性:interpolator 指定一個動畫的插入器
         試驗過程中,使用android.res.anim中的資源時候發現
            有三種動畫插入器:
                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方向座標上的中點位置

                長整型值:
                    duration  屬性為動畫持續時間
                 說明:   時間以毫秒為單位

                 布林型值:
                    fillAfter 屬性 當設定為true ,該動畫轉化在動畫結束後被應用
    -->
    <scale
        android:duration="5000"
        android:fillAfter="false"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.4"
        android:toYScale="1.4" />

    <!--
     translate 位置轉移動畫效果
         整型值:
            fromXDelta 屬性為動畫起始時 X座標上的位置    
            toXDelta   屬性為動畫結束時 X座標上的位置
            fromYDelta 屬性為動畫起始時 Y座標上的位置
            toYDelta   屬性為動畫結束時 Y座標上的位置
                         注意:
                                    沒有指定fromXType toXType fromYType toYType 時候,
                                     預設是以自己為相對參照物             
                        長整型值:
            duration  屬性為動畫持續時間
                         說明:   時間以毫秒為單位
    -->
    <translate
        android:duration="5000"
        android:fromXDelta="30"
        android:fromYDelta="30"
        android:toXDelta="-80"
        android:toYDelta="300" />

    <!--
     rotate 旋轉動畫效果
        屬性:interpolator 指定一個動畫的插入器
                試驗過程中,使用android.res.anim中的資源時候發現
                有三種動畫插入器:
                    accelerate_decelerate_interpolator   加速-減速 動畫插入器
                    accelerate_interpolator               加速-動畫插入器
                    decelerate_interpolator               減速- 動畫插入器
                其他的屬於特定的動畫效果

                    浮點數型值:
                        fromDegrees 屬性為動畫起始時物件的角度    
                        toDegrees   屬性為動畫結束時物件旋轉的角度 可以大於360度   


                     說明:
                         當角度為負數——表示逆時針旋轉
                        當角度為正數——表示順時針旋轉              
                        (負數from——to正數:順時針旋轉)   
                        (負數from——to負數:逆時針旋轉) 
                        (正數from——to正數:順時針旋轉) 
                        (正數from——to負數:逆時針旋轉)       

                    pivotX     屬性為動畫相對於物件的X座標的開始位置
                    pivotY     屬性為動畫相對於物件的Y座標的開始位置

                     說明:        以上兩個屬性值 從0%-100%中取值
                         50%為物件的X或Y方向座標上的中點位置

                    長整型值:
                        duration  屬性為動畫持續時間
                    說明:       時間以毫秒為單位
    -->
    <rotate
        android:duration="5000"
        android:fromDegrees="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="0%"
        android:pivotY="100%"
        android:toDegrees="-600" />
</set>

②Java問價中引入

private Animation loadAnimation (Context context,int id){
        //第一個引數Context為程式的上下文    
        //第二個引數id為動畫XML檔案的引用
        Animation mtAnimation = AnimationUtils.loadAnimation(context, id);
        return mtAnimation;
    }

③Java控制元件使用。

iv = (ImageView) findViewById(R.id.iv);
        Animation myAnimation;
        myAnimation = loadAnimation(getApplicationContext(),R.anim.my_anim_alpha);
        iv.startAnimation(myAnimation);
  1. Java程式碼實現
    不用xml檔案完全用Java程式碼實現,除了完全能夠實現xml所有功能外,還可以實現動畫的屬性值的動態的調整。
    實現流程:
    ①Java程式碼實現動作效果
private Animation javaAnimation(){
        myAnimation_Alpha = new AlphaAnimation(0.1f, 1.0f);
        myAnimation_Alpha.setDuration(5000);

        //ScaleAnimation(float fromX, float toX, float fromY, float toY,
        //           int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) 

        //第一個引數fromX為動畫起始時 X座標上的伸縮尺寸    
        //第二個引數toX為動畫結束時 X座標上的伸縮尺寸     
        //第三個引數fromY為動畫起始時Y座標上的伸縮尺寸    
        //第四個引數toY為動畫結束時Y座標上的伸縮尺寸  
        /*說明:
                            以上四種屬性值    
                            0.0表示收縮到沒有 
                            1.0表示正常無伸縮     
                            值小於1.0表示收縮  
                            值大於1.0表示放大
        */
        //第五個引數pivotXType為動畫在X軸相對於物件位置型別  
        //第六個引數pivotXValue為動畫相對於物件的X座標的開始位置
        //第七個引數pivotXType為動畫在Y軸相對於物件位置型別   
        //第八個引數pivotYValue為動畫相對於物件的Y座標的開始位置
        myAnimation_Scale = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        myAnimation_Scale.setDuration(5000);

        //第一個引數fromXDelta為動畫起始時 X座標上的移動位置    
        //第二個引數toXDelta為動畫結束時 X座標上的移動位置      
        //第三個引數fromYDelta為動畫起始時Y座標上的移動位置     
        //第四個引數toYDelta為動畫結束時Y座標上的移動位置
        myAnimation_Translate = new TranslateAnimation(30.0f, -80.f, 30.0f, 300.0f);
        myAnimation_Translate.setDuration(5000);

        //RotateAnimation(float fromDegrees, float toDegrees,int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
        //第一個引數fromDegrees為動畫起始時的旋轉角度    
        //第二個引數toDegrees為動畫旋轉到的角度   
        //第三個引數pivotXType為動畫在X軸相對於物件位置型別  
        //第四個引數pivotXValue為動畫相對於物件的X座標的開始位置
        //第五個引數pivotXType為動畫在Y軸相對於物件位置型別   
        //第六個引數pivotYValue為動畫相對於物件的Y座標的開始位置
        myAnimation_Rotate=new RotateAnimation(0.0f, +350.0f,Animation.RELATIVE_TO_SELF,0.0f,Animation.RELATIVE_TO_SELF, 1.0f);
        myAnimation_Rotate.setDuration(5000);
        myAnimation_Rotate.setFillAfter(true);//動畫在播放結束時是否保持最終的狀態
        myAnimation_Rotate.setRepeatCount(2);//動畫的重複次數
        myAnimation_Rotate.setRepeatMode(Animation.RESTART);
        return myAnimation_Rotate;
    }

②與控制元件繫結

iv = (ImageView) findViewById(R.id.iv);
        Animation myAnimation;
//        myAnimation = loadAnimation(getApplicationContext(),R.anim.my_anim_alpha);
        myAnimation = javaAnimation();
        iv.startAnimation(myAnimation);

自定義View動畫
除了補間動畫提供的四種動畫外,還可以自定義動畫。
實現方法:
接下來參考《Android開發藝術探索》

  1. 派生一種新的動畫只需繼承Animation這個抽象類;
    1. 重寫他的initialize和applyTransformation方法;在initialize方法中做初始化工作,在applyTransformation方法中進行相應的矩陣變換。

難點: 自定義View動畫的過程主要通過矩陣變換的過程,矩陣變換!

ok,至此 簡單的補間動畫也學習了。

View動畫的特許使用場景
View動畫的四種形式,除了這四種形式外,View動畫還可以在一些特許場景下使用,

  1. ViewGroup中可以控制子元素的出場效果;
  2. 在Activity中實現不同Activity之間的切換效果。

LayoutAnimation
LayoutAnimation作用於ViewGroup,為ViewGroup指定一個動畫,當他的子元素出場時都會具有這種動畫效果。
這種效果常用語ListView上,他的每一個item都已一定的動畫形式出現。

Activity的切換效果
Activity有預設的切換效果,但這個效果我們也可以自定義;
方法:
overridePendingTransition(int enterAnim,int eixtAnim);
在startActivity(Intent)或者finish()之後被呼叫才生效;
enterAnim——Activity被開啟時所需要的動畫資源ID;
eixtAnim —— Activity被暫停時所需要的動畫資源ID;

public void clickMe(View view){
        Intent intent = new Intent(getApplicationContext(),OtherAty.class);
        startActivity(intent);
        overridePendingTransition(R.anim.push_bottom_in, 0);
    }
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
        android:fromYDelta="0"
        android:toYDelta="100%p"
        android:duration="300"
        />

</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate 
        android:fromYDelta="100%p"
        android:toYDelta="0"
        android:duration="300"/>

</set>
public void finishSelf(View view){
        finish();
        overridePendingTransition(0, R.anim.push_bottom_out);
    }

Fragment也可以新增切換動畫,通過FragmentTransaction中的setCustomAnimations()方法來新增切換動畫。

ok,接下來,屬性動畫。