有時要對控件添加一點動畫效果,在安卓中,動畫效果也是一個類,也就是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();
}
