本文是對Tween Animation動畫的詳解,由於變化動畫有很多種方式,而且每一個動畫都可以使用java代碼和XML佈局來實現.所以我覺得不必死記代碼,只需要知道一個動畫效果需要用哪種方式去實現即可.具體代碼可參考如下:
在實現本文所有例子之前,你須在Android Studio res目錄下右鍵新建一個director取名爲anim 用於存放動畫的XML
Demo截圖如下:
閃光燈截圖如下:
ListView飛入截圖如下:
(1).縮放動畫
XML代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:pivotX="0%"
android:pivotY="50%"
android:fromXScale="1.0"
android:fromYScale="1.0"
android:toXScale="0.1"
android:toYScale="0.1"
android:fillAfter="true">
<!--
scale表示縮放動畫 是Tween Animation(變化動畫的一種)
android:duration="2000" 表示動畫播放的時間爲2000毫秒(開始縮放到縮放結束) 沒有代碼提示
android:fromXScale="1"表示縮放之前X軸的大小(0表示完全縮放,即不可見狀態,1,表示沒有原來大小)
android:fromYScale="1"表示縮放之前Y軸的大小
android:toXScale="0" 表示縮放之後X軸的大小
android:toYScale="0" 表示縮放之後Y軸的大小
android:pivotX="50%", android:pivotY="50%"表示在X,Y軸上縮放的位置,
這裏設置爲50%,所以圖片以自己的中心點縮放
android:fillAfter="ture" 表示保持縮放之後的狀態
爲false 表示縮放之後回覆到初始狀態 (沒有代碼提示)
-->
</scale>
Java引用動畫代碼如下:
package myself.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private Button button;
private ImageView imageView;
private Animation animation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button) findViewById(R.id.button1);
imageView = (ImageView) findViewById(R.id.imageView);
//得到anim目錄下的XML佈局動畫
animation = AnimationUtils.loadAnimation(this, R.anim.scale_anim);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//圖片播放動畫
imageView.startAnimation(animation);
}
});
}
}
(2)透明度動畫
XML代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:fromAlpha="1.0"
android:toAlpha="0"
android:duration="2000"
android:fillAfter = "false">
<!--
alpha表示透明度動畫
0.0 至 1.0之間浮點型小數 0.0表示完全透明,1.0表示不透明
android:fromAlpha=""改變之前的透明度
android:toAlpha="" 改變之後的透明度
-->
</alpha>
(3)旋轉動畫
XML代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:toDegrees="+360"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
<!--
rotate表示旋轉動畫
android:fromDegrees="",android:toDegrees=""
分別表示開始旋轉時的角度和旋轉的角度,
當toDegrees的值大於fromDegrees的時候逆時針旋轉,
反之順時針旋轉
-->
(4)位移動畫
XML代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="-100"
android:toYDelta="100"
android:duration="2000"
android:fillAfter="true">
</translate>
<!--
translate表示位移動畫
android:fromXDelta="0"
android:fromYDelta="0"表示該控件的起始座標,以左上角爲座標原點
android:toXDelta="100"
android:toYDelta="100"表示控件位移之後的座標.
判斷位移的位置可以想象數學上的座標軸,但與數軸又有不同
數軸上是:右正左負,上正下負
屏幕上是:右正左負,上負下正
-->
(5)組合動畫
XML代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:duration="2000"
android:fromDegrees="0"
android:toDegrees="+360"
android:pivotX="50%"
android:pivotY="50%">
</rotate>
<translate
android:fromXDelta="0"
android:fromYDelta="0"
android:toXDelta="100"
android:toYDelta="100"
android:duration="2000"
android:fillAfter="true"
android:startOffset="2000">
</translate>
<!--
set在這裏可以理解爲一個動畫的集合, 裏面可以放你定義好的動畫類型
需要特別注意的是:如果你想這一個動畫播放完再播放下一個動畫
那麼android:startOffset="2000"必須大於或等於你
上一個動畫的android:duration="2000" 即第二個動畫的開始時間
必須大於或等於你上一個動畫的播放時間,否則他們會一起播放
-->
</set>
java代碼引用以上動畫如下:
package myself.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.TextView;
public class SecondActivity extends AppCompatActivity implements View.OnClickListener{
private TextView textView;
private Button b1,b2,b3,b4,b5,b6,b7;
private Animation anim;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
textView = (TextView) findViewById(R.id.textView2);
//改變透明度的按鈕Button點擊事件
b1 = (Button) findViewById(R.id.button1);
b1.setOnClickListener(this);
//旋轉的Button點擊事件
b2 = (Button) findViewById(R.id.button2);
b2.setOnClickListener(this);
//位移的Button點擊事件
b3 = (Button) findViewById(R.id.button3);
b3.setOnClickListener(this);
//通過java代碼實現組合動畫
b4 = (Button)findViewById(R.id.button4);
b4.setOnClickListener(this);
//通過XML實現組合動畫
b5 = (Button) findViewById(R.id.button5);
b5.setOnClickListener(this);
//通過java代碼實現文字閃爍
b6 = (Button) findViewById(R.id.button6);
b6.setOnClickListener(this);
//通過java代碼實現文字抖動
b7 = (Button) findViewById(R.id.button7);
b7.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//匹配各個Button的點擊事件
switch (v.getId()){
//改變透明度的按鈕Button點擊事件
case R.id.button1:
anim = AnimationUtils.loadAnimation(this,R.anim.alpha_anim);
textView.startAnimation(anim);
break;
//旋轉的Button點擊事件
case R.id.button2:
anim = AnimationUtils.loadAnimation(this,R.anim.rotate_anim);
textView.startAnimation(anim);
break;
//位移的Button點擊事件
case R.id.button3:
anim = AnimationUtils.loadAnimation(this,R.anim.translate_anim);
textView.startAnimation(anim);
break;
//通過java代碼實現組合動畫
case R.id.button4:
//首先拿到兩種已經在XML裏面定義好的動畫
Animation anim1 = AnimationUtils.loadAnimation(this, R.anim.rotate_anim);
final Animation anim2 = AnimationUtils.loadAnimation(this, R.anim.translate_anim);
//設置動畫監聽器
anim1.setAnimationListener(new Animation.AnimationListener() {
//動畫開始時會被觸發
@Override
public void onAnimationStart(Animation animation) {
}
//動畫結束時會被觸發
@Override
public void onAnimationEnd(Animation animation) {
//在anim1動畫結束後開始播放動畫anim2
textView.startAnimation(anim2);
}
//動畫重複是會被觸發
@Override
public void onAnimationRepeat(Animation animation) {
}
});
//播放動畫anim1
textView.startAnimation(anim1);
break;
//通過XML實現組合動畫
case R.id.button5:
anim = AnimationUtils.loadAnimation(this,R.anim.set_anim);
textView.startAnimation(anim);
break;
//通過java代碼實現文字閃爍
case R.id.button6:
//所謂的文字或者圖片閃爍,實際上是透明度的快速切換,
//因此我們需要一個改變透明度的類
AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f,0.0f);
//設置動畫播放時長
alphaAnimation.setDuration(200);
//設置動畫重複次數
alphaAnimation.setRepeatCount(20);
/**
*Animation.REVERSE表示動畫重複模式爲逆序重複
*Animation.RESTART表示動畫重複模式爲正序重複
*
* 就本例改變透明度閃爍文字來說
* 正序重複:1.0-->0.0 1.0-->0.0 1.0-->0.0 1.0-->0.0
* 逆序重複:1.0-->0.0 0.0-->1.0 1.0-->0.0 0.0-->1.0
*
* 所以某些時候逆序重複的給人的感覺比較連續
*/
alphaAnimation.setRepeatMode(Animation.REVERSE);
textView.startAnimation(alphaAnimation);
break;
//通過java代碼實現文字抖動
case R.id.button7:
//所謂的文字抖動,實際上是快速的短距離位移形成的效果
TranslateAnimation ta = new TranslateAnimation(-10, 10, 0, 0);
//設置動畫播放時間
ta.setDuration(100);
//設置播放次數
ta.setRepeatCount(20);
//設置播放順序(逆序播放)
ta.setRepeatMode(Animation.REVERSE);
//加載動畫
textView.startAnimation(ta);
break;
}
}
}
製作閃光燈的時候你需要兩張圖片,一張燈亮,一張燈滅.並在製作一個選擇器,組裝這兩張圖片,然後用ImageView引用這個選擇器,最後在java代碼中用線程延時調用
選擇器代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/w_warning_light_on"></item>
<item android:state_selected="false" android:drawable="@drawable/w_warning_light_off"></item>
<item android:drawable="@drawable/w_warning_light_off"></item>
</selector>
java代碼如下:
package myself.myapplication;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
/**
*通過線程切換兩張圖片,模擬閃光燈的效果
*/
public class FlashBulb extends AppCompatActivity implements View.OnClickListener {
private Button btn1, btn2;
private ImageView imageView;
//線程間的使者
private Handler handler = new Handler();
private Runnable thread = new Runnable() {
@Override
public void run() {
//如果圖片被選中了
if(imageView.isSelected()){
//反選它
imageView.setSelected(false);
}else{
imageView.setSelected(true);
}
//延時調用線程
handler.postDelayed(thread, 100);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash_bulb);
btn1 = (Button) findViewById(R.id.start);
btn1.setOnClickListener(this);
btn2 = (Button) findViewById(R.id.stop);
btn2.setOnClickListener(this);
imageView = (ImageView) findViewById(R.id.flash);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.start:
//調用線程
handler.postDelayed(thread, 100);
break;
case R.id.stop:
//刪除線程
handler.removeCallbacks(thread);
break;
}
}
}
ListView飛入效果實現之前須在anim目錄下定義一個組合動畫,代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="500"
android:fromXDelta="300"
android:fromYDelta="0"
android:toXDelta="0"
android:toYDelta="0" />
<alpha
android:duration="500"
android:fromAlpha="0.0"
android:toAlpha="1.0" />
<!--
飛入動畫是位移動畫和透明度動畫的組合體
位移的同時ListView的每一項Item從無到有的出現
它們的動畫時間必須是一致的
-->
</set>
java代碼如下:
package myself.myapplication;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
/**
* 實現ListView右飛入的效果
*/
public class RightIn extends AppCompatActivity {
private ListView listView;
private ArrayAdapter adapter;
private List<String>list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_right_in);
//實例化控件
listView = (ListView) findViewById(R.id.listView);
//準備數據
list = new ArrayList<>();
for (int i = 1; i <= 20; i++) {
String s = "##########第"+i+"行##########";
list.add(s);
}
adapter = new ArrayAdapter(RightIn.this, android.R.layout.simple_list_item_1,
android.R.id.text1, list);
//視圖控件加載適配器
listView.setAdapter(adapter);
//佈局文件加載動畫
LayoutAnimationController lac = new LayoutAnimationController(
AnimationUtils.loadAnimation(this,R.anim.right_in_anim));
/**
* ORDER_NORMAL:播放順序爲從上到下
* ORDER_REVERSE:播放順序爲從下到上
* ORDER_RANDOM:爲亂序播放
*/
lac.setOrder(LayoutAnimationController.ORDER_NORMAL);
//視圖控件加載佈局動畫
listView.setLayoutAnimation(lac);
//開始播放動畫
listView.startLayoutAnimation();
}
}