有時要對控件添加一點動畫效果,在安卓中,動畫效果也是一個類,也就是Animation類。把動畫效果這個類弄好后,在與控件類關聯到一起,就可以實現控件有一些動作特效這樣的效果了。動畫效果的定義,要在xml文件中。
效果圖:
屏幕錄制有些卡頓。不過影響不大。
以上的例子其實只是用了ImageView這個控件,然后不同的控件用了逐漸放大,還有位置平移這個動作。
下面說說怎么實現:
先實例化Animation類:
Animation myAnimation; //通過loadAnimation函數 把動畫效果的xml文件加載進來 實例化動作類 myAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.my_anim);
實現xml文件(以下給出自帶的4種特效):
alpha 漸變透明度動畫效果
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <alpha android:duration="1000" android:fromAlpha="0.0" android:toAlpha="1.0" /> <!-- 透明度控制動畫效果 alpha 漸變透明度動畫效果 浮點型值: fromAlpha 屬性為動畫起始時透明度 toAlpha 屬性為動畫結束時透明度 說明: 0.0表示完全透明 1.0表示完全不透明 以上值取0.0-1.0之間的float數據類型的數字 長整型值: duration 屬性為動畫持續時間 說明: 時間以毫秒為單位 --> </set>
scale 漸變尺寸伸縮動畫效果
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <scale android:duration="1000" 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" /> </set><!-- 尺寸伸縮動畫效果 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 ,該動畫轉化在動畫結束后被應用
-->
translate 畫面轉換位置移動動畫效果
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="2000" android:fromXDelta="30" android:fromYDelta="30" android:toXDelta="-80" android:toYDelta="300" /> <!-- translate 位置轉移動畫效果 整型值: fromXDelta 屬性為動畫起始時 X坐標上的位置 toXDelta 屬性為動畫結束時 X坐標上的位置 fromYDelta 屬性為動畫起始時 Y坐標上的位置 toYDelta 屬性為動畫結束時 Y坐標上的位置 注意: 沒有指定fromXType toXType fromYType toYType 時候, 默認是以自己為相對參照物 長整型值: duration 屬性為動畫持續時間 說明: 時間以毫秒為單位 --> </set>
rotate 畫面轉移旋轉動畫效果
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <rotate android:duration="3000" android:fromDegrees="0" android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:pivotX="50%" android:pivotY="50%" android:toDegrees="+350" /> <!-- 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 屬性為動畫持續時間 說明: 時間以毫秒為單位 --> </set>
把Animation類和控件關聯在一起
//控件開始動作 imgPic.startAnimation(myAnimation);
挺簡單的吧,只要先實現xml文件,定義好動作的類型。再通過loadAnimation函數,用xml文件實例化Animaiton類。然后再把animaiton類和控件類關聯在一起,控件就會開始有動作效果了。
不過要注意的是:animation類只能運行在主線程中!!!!!!
而且我發現一個問題,直接在代碼中加入動作效果,不會自動執行。並且如果同時定義了多個有動作效果的控件的話,他們是會同時執行的,那有什么辦法可以按順序執行呢?
結合到UI還有主線程的問題,很自然就想到了Handler類。
我的解決辦法是:進入activity后,開啟一個新線程,這個線程按我們的需求,發消息給Handler類來執行動作,這樣就可以執行了。
這是在onCreate里面的代碼:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //用於更新在主線程的UI handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.arg1){ case 0: { myAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.my_anim); imgPic.startAnimation(myAnimation); imgPic.setVisibility(View.VISIBLE); }break; case 1: { myAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.studio_anim); LWGstudio.startAnimation(myAnimation); LWGstudio.setVisibility(View.VISIBLE); }break; case 2: { backAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.back_anim); back.startAnimation(backAnimation); back.setVisibility(View.VISIBLE); }break; } } }; //透明狀態欄 getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); imgPic = (ImageView)findViewById(R.id.ask); imgPic.setVisibility(View.INVISIBLE); back = (ImageView)findViewById(R.id.firstback); back.setVisibility(View.INVISIBLE); LWGstudio = (ImageView)findViewById(R.id.LWGstudio); LWGstudio.setVisibility(View.INVISIBLE); new Thread(new Runnable() { @Override public void run() { //進去隔一秒 出現askFood try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } Message ok = new Message(); ok.arg1 = 0;//區分更新什么UI handler.sendMessage(ok); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } //第一個動作執行后,隔兩秒執行LWGstudio出現的動作 ok = new Message(); ok.arg1 = 1;//區分更新什么UI handler.sendMessage(ok); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //最后出現全屏變綠的動作 ok = new Message(); ok.arg1 = 2;//區分更新什么UI handler.sendMessage(ok); } }).start(); }