天天看點

Android動畫之Tween動畫實作

Android 平台提供了兩類動畫。 一類是Tween動畫,就是對場景裡的對象不斷的進行圖像變化來産生動畫效果(旋轉、平移、放縮和漸變)。

第二類就是 Frame動畫,即順序的播放事先做好的圖像,與gif圖檔原理類似。

下面就講一下Tweene Animations。

 主要類:

 Animation  動畫

AlphaAnimation 漸變透明度

RotateAnimation 畫面旋轉

ScaleAnimation 漸變尺寸縮放

TranslateAnimation 位置移動

AnimationSet  動畫集

一、等待動畫實作

在我們應用程式當中,經常會使用到等待動畫,那麼首先我們就來實作這個

1.1首先,當然是布局啦

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#fff"
    >
    <RelativeLayout
        android:layout_width="180dp"
        android:layout_height="180dp"
        android:layout_centerInParent="true"
        android:background="@drawable/loading_bg" >
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:gravity="center"
            android:orientation="vertical" >
            <ProgressBar
        		android:id="@+id/progressBar1"
        		style="?android:attr/progressBarStyleLarge"
        		android:layout_width="wrap_content"
        		android:layout_height="wrap_content"        
        		android:layout_gravity="center_horizontal"
         	/>
        	<TextView
        		android:layout_width="wrap_content"
        		android:layout_height="wrap_content"
        		android:text="正在登入"
       			android:layout_marginTop="10dp"
        		android:textColor="#fff"
        		android:textSize="20sp"
        />
        </LinearLayout>
    </RelativeLayout>
</RelativeLayout>
           

1.2其次,就是實作啦

MainActivity.java

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//延遲一段時間後跳轉到另一個界面
		new Handler().postDelayed(new Runnable(){
			@Override
			public void run(){
				Intent intent = new Intent(MainActivity.this,SecondActivity.class);
				startActivity(intent);
				MainActivity.this.finish();
				Toast.makeText(getApplicationContext(), "跳轉成功", Toast.LENGTH_SHORT).show();
			}
		}, 2000);
	}
}
           

1.3實作效果如圖

Android動畫之Tween動畫實作

二、開門動畫實作

2.1首先,當然是布局啦

second.xml

<?xml version="1.0" encoding="UTF-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#000"
         >
        
        <ImageView
            android:id="@+id/imageLeft"
            android:scaleType="fitXY"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_alignParentLeft="true"
            android:src="@drawable/w_left" />
        <ImageView
            android:id="@+id/imageRight"
            android:visibility="visible"
            android:scaleType="fitXY"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_alignParentRight="true"            
            android:src="@drawable/w_right" />
        <TextView 
            android:id="@+id/anim_text"
        	android:layout_width="fill_parent" 
        	android:layout_height="wrap_content" 
        	android:gravity="center" 
        	android:layout_alignParentTop="true"
            android:layout_marginTop="35dp"
        	android:text=" \n \nthis is a test!\n \n "         	
        	android:textSize="22sp"
        	android:textColor="#fff" 
        />

    </RelativeLayout>
           

2.2其次,就是實作啦

SecondActivity.java

public class SecondActivity extends Activity 
{
	private ImageView mLeft;
	private ImageView mRight;
	private TextView mText;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.second);
		
		mLeft = (ImageView)findViewById(R.id.imageLeft);
        mRight = (ImageView)findViewById(R.id.imageRight);
        mText = (TextView)findViewById(R.id.anim_text);
        
        //往左移動
        AnimationSet anim = new AnimationSet(true);
		TranslateAnimation mytranslateanim = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,-1f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f);
		mytranslateanim.setDuration(2000);
		anim.setStartOffset(800);
		anim.addAnimation(mytranslateanim);
		anim.setFillAfter(true);
		mLeft.startAnimation(anim);
		
		//往右移動
		AnimationSet anim1 = new AnimationSet(true);
		TranslateAnimation mytranslateanim1 = new TranslateAnimation(Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,+1f,Animation.RELATIVE_TO_SELF,0f,Animation.RELATIVE_TO_SELF,0f);
		mytranslateanim1.setDuration(1500);
		anim1.addAnimation(mytranslateanim1);
		anim1.setStartOffset(800);
		anim1.setFillAfter(true);
		mRight.startAnimation(anim1);
		
		//文字變換
		AnimationSet anim2 = new AnimationSet(true);
		ScaleAnimation myscaleanim = new ScaleAnimation(1f,3f,1f,3f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
		myscaleanim.setDuration(1000);
		AlphaAnimation myalphaanim = new AlphaAnimation(1,0.0001f);
		myalphaanim.setDuration(1500);
		anim2.addAnimation(myscaleanim);
		anim2.addAnimation(myalphaanim);
		anim2.setFillAfter(true);
		mText.startAnimation(anim2);
		
		
		//持續一段時間後跳轉
		new Handler().postDelayed(new Runnable(){
			@Override
			public void run(){
				Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);
				startActivity(intent);
				SecondActivity.this.finish();
			}
		}, 2000);
	}
	
}
           

2.3實作效果如圖

Android動畫之Tween動畫實作
Android動畫之Tween動畫實作
Android動畫之Tween動畫實作
Android動畫之Tween動畫實作

三、透明旋轉縮放移動動畫實作及其混合實作

3.1首先,當然是布局啦

third.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#000" >
    
    <TextView 
        android:id="@+id/tv1"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="透明動畫測試AlphaAnimation"
        android:textColor="#f00"
        android:textSize="20sp"/>
    
    <View 
        android:layout_width="fill_parent"
        android:layout_height="10dip"
        android:background="?android:attr/listDivider"/>
    
    <TextView 
        android:id="@+id/tv2"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="旋轉動畫測試RotateAnimation"
        android:textColor="#0f0"
        android:textSize="20sp"/>
    
    <View 
        android:layout_width="fill_parent"
        android:layout_height="10dip"
        android:background="?android:attr/listDivider"/>
    
    <TextView 
        android:id="@+id/tv3"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="縮放動畫測試ScaleAnimation"
        android:textColor="#00f"
        android:textSize="20sp"/>
    
    <View 
        android:layout_width="fill_parent"
        android:layout_height="10dip"
        android:background="?android:attr/listDivider"/>
    
    <TextView 
        android:id="@+id/tv4"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="移動動畫測試TranslateAnimation"
        android:textColor="#ff0"
        android:textSize="20sp"/>
    
    <View 
        android:layout_width="fill_parent"
        android:layout_height="10dip"
        android:background="?android:attr/listDivider"/>
    
    <TextView 
        android:id="@+id/tv5"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="多個動畫同時生效測試AnimationSet"
        android:textColor="#f0f"
        android:textSize="20sp"/>
    

</LinearLayout>
           

3.2其次,就是實作啦

ThirdActivity.java

public class ThirdActivity extends Activity
{
	private TextView mTextView1 = null;
	private TextView mTextView2 = null;
	private TextView mTextView3 = null;
	private TextView mTextView4 = null;
	private TextView mTextView5 = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.third);
		
		//透明動畫測試 AlphaAnimation
		mTextView1 = (TextView)findViewById(R.id.tv1);
		//初始化 其中AlphaAnimation類第一個參數fromAlpha表示動畫起始時的透明度,第二個參數toAlpha表示動畫結束時的透明度
		Animation alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
		//設定動畫時間 setDuration用來設定動畫持續時間
		alphaAnimation.setDuration(5000);
		mTextView1.startAnimation(alphaAnimation);
		/*其中AlphaAnimation類第一個參數fromAlpha表示動畫起始時的透明度, 第二個參數toAlpha表示動畫結束時的透明度。 
			setDuration用來設定動畫持續時間。*/
		
		//旋轉動畫測試 RotateAnimation
		mTextView2 = (TextView)findViewById(R.id.tv2);
		Animation rotateAnimation = new RotateAnimation(0f, 360f);
		rotateAnimation.setDuration(5000);
		mTextView2.startAnimation(rotateAnimation);
		/*其中RotateAnimation類第一個參數fromDegrees表示動畫起始時的角度, 第二個參數toDegrees表示動畫結束時的角度。 
			另外還可以設定伸縮模式pivotXType、pivotYType, 伸縮動畫相對于x,y 坐标的開始位置pivotXValue、pivotYValue等。*/
		
		//縮放動畫測試 ScaleAnimation
		mTextView3 = (TextView)findViewById(R.id.tv3);
		//初始化
		Animation scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);
		//設定動畫時間
		scaleAnimation.setDuration(5000);
		mTextView3.startAnimation(scaleAnimation);
		/*第一個參數fromX ,第二個參數toX:分别是動畫起始、結束時X坐标上的伸縮尺寸。
			第三個參數fromY ,第四個參數toY:分别是動畫起始、結束時Y坐标上的伸縮尺寸。
			另外還可以設定伸縮模式pivotXType、pivotYType, 伸縮動畫相對于x,y 坐标的開始位置pivotXValue、pivotYValue等。*/
		
		//移動動畫測試 TranslateAnimation
		mTextView4 = (TextView)findViewById(R.id.tv4);
		//初始化
		Animation translateAnimation = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);
		//設定動畫時間
		translateAnimation.setDuration(5000);
		mTextView4.startAnimation(translateAnimation);
		/*第一個參數fromXDelta ,第二個參數toXDelta:分别是動畫起始、結束時X坐标。
			第三個參數fromYDelta ,第四個參數toYDelta:分别是動畫起始、結束時Y坐标。*/
		
		
		//多個動畫同時生效 AnimationSet
		mTextView5 = (TextView)findViewById(R.id.tv5);
		//初始化 Alpha動畫
		Animation alphaAnimation5 = new AlphaAnimation(0.1f, 1.0f);
		//初始化 Rotate動畫
		Animation rotateAnimation5 = new RotateAnimation(0f, 360f);
		//初始化 Scale動畫
		Animation scaleAnimation5 = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);
		//初始化 Translate動畫
		Animation translateAnimation5 = new TranslateAnimation(0.1f, 100.0f,0.1f,100.0f);
		//動畫集
		AnimationSet set = new AnimationSet(true);
		set.addAnimation(alphaAnimation5);
		set.addAnimation(rotateAnimation5);
		set.addAnimation(scaleAnimation5);
		set.addAnimation(translateAnimation5);
		//設定動畫時間 (作用到每個動畫)
		set.setDuration(5000);
		mTextView5.startAnimation(set);
		
		new Handler().postDelayed(new Runnable(){
			@Override
			public void run(){
				Intent intent = new Intent(ThirdActivity.this,FourActivity.class);
				startActivity(intent);
				ThirdActivity.this.finish();
			}
		}, 6000);
	}
}
           

3.3實作效果如圖

Android動畫之Tween動畫實作
Android動畫之Tween動畫實作

四、重寫View實作動畫效果

4.1首先,重寫View

TweenAnim.java

public class TweenAnim extends View 
{
	//Alpha動畫 - 漸變透明度
	private Animation alphaAnimation = null;
	//Sacle動畫 - 漸變尺寸縮放
	private Animation scaleAnimation = null;
	//Translate動畫 - 位置移動
	private Animation translateAnimation = null;
	//Rotate動畫 - 畫面旋轉
	private Animation rotateAnimation = null;
	
	public TweenAnim(Context context) {
		super(context);
		
		//初始化 Alpha動畫
		alphaAnimation = new AlphaAnimation(0.1f, 1.0f);
		//初始化 Rotate動畫
		rotateAnimation = new RotateAnimation(0f, 360f);
		//初始化 Scale動畫
		scaleAnimation = new ScaleAnimation(0.1f, 1.0f,0.1f,1.0f);
		//初始化 Translate動畫
		translateAnimation = new TranslateAnimation(0.1f, 300.0f,0.1f,300.0f);
		
		//動畫集
		AnimationSet set = new AnimationSet(true);
		set.addAnimation(alphaAnimation);
		set.addAnimation(rotateAnimation);
		set.addAnimation(scaleAnimation);
		set.addAnimation(translateAnimation);
		
		//設定動畫時間 (作用到每個動畫)
		set.setDuration(5000);
		this.startAnimation(set);
		
	}
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Log.e("Tween", "onDraw");
		//加載一個圖檔
		canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(R.drawable.background1)).getBitmap(), 0, 0, null);
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		Log.e("Tween", "onKeyDown");
		return true;
	}
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		Log.e("Tween", "onKeyDown");
		switch (keyCode) {
			case KeyEvent.KEYCODE_DPAD_UP:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_UP");
				break;
			case KeyEvent.KEYCODE_DPAD_DOWN:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_DOWN");
				break;
			case KeyEvent.KEYCODE_DPAD_LEFT:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_LEFT");
				break;
			case KeyEvent.KEYCODE_DPAD_RIGHT:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_RIGHT");
				break;
			case KeyEvent.KEYCODE_DPAD_CENTER:
				break;
			default:
				break;
		}
		return true;
	}
}
           

在Activity中調用該類時,需要注意一定setFocusable(true), 否則焦點在Activity上的話,onKeyUp方法是不會生效的。

4.2其次,就是實作啦

FourActivity.java

public class FourActivity extends Activity
{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		TweenAnim anim = new TweenAnim(FourActivity.this);
		anim.setFocusable(true);
		setContentView(anim);
		
		new Handler().postDelayed(new Runnable(){
			@Override
			public void run(){
				Intent intent = new Intent(FourActivity.this,FiveActivity.class);
				startActivity(intent);
				FourActivity.this.finish();
			}
		}, 6000);
	}
}
           

4.3實作效果如圖

Android動畫之Tween動畫實作
Android動畫之Tween動畫實作
Android動畫之Tween動畫實作

五、利用XML實作動畫效果

5.1布局檔案

透明度alpha_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<alpha
		android:fromAlpha="0.1"
		android:toAlpha="1.0"
		android:duration="2000"
	/>
</set>
           

alpha動畫參數

XML節點 功能說明
alpha 透明度動畫
fromAlpha

動畫起始時透明度

0.0表示完全透明

1.0表示完全不透明

以上值取0.0-1.0之間的float資料類型的數字

toAlpha 動畫結束時透明度

旋轉rotate_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<rotate
		android:interpolator="@android:anim/accelerate_decelerate_interpolator"
		android:fromDegrees="0"
		android:toDegrees="360"
		android:pivotX="50%"
		android:pivotY="50%"
		android:duration="2000"
	/>
</set>
           

rotate動畫參數

XML節點 功能說明
rotate 旋轉動畫
fromDegrees

動畫起始時物件的角度

當角度為負數——表示逆時針旋轉

當角度為正數——表示順時針旋轉

(負數from——to正數:順時針旋轉)

(負數from——to負數:逆時針旋轉)

(正數from——to正數:順時針旋轉)

(正數from——to負數:逆時針旋轉)

toDegrees 屬性為動畫結束時物件旋轉的角度 可以大于360度

pivotX

pivotY

為動畫相對于物件的X、Y坐标的開始位

以上兩個屬性值 從0%-100%中取值

50%為物件的X或Y方向坐标上的中點位置

縮放scale_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<scale
		android:interpolator="@android:anim/accelerate_decelerate_interpolator"
		android:fromXScale="0.0"
		android:toXScale="1.0"
		android:fromYScale="0.0"
		android:toYScale="1.0"
		android:pivotX="50%"
		android:pivotY="50%"
		android:fillAfter="false"
		android:duration="2000"
	/>	
</set>
           

scale動畫參數

XML節點 功能說明
scale 縮放動畫

fromXScale[float]

fromYScale[float]

動畫起始時,X、Y坐标上的伸縮尺寸

0.0表示收縮到沒有

1.0表示正常無伸縮

值小于1.0表示收縮

值大于1.0表示放大

toXScale [float]

toYScale[float]

動畫結束時,X、Y坐标上的伸縮尺寸

pivotX[float]

pivotY[float]

動畫相對于物件的X、Y坐标的開始位置

從0%-100%中取值,50%為物件的X或Y方向坐标上的中點位置

移動translate_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
	<translate
		android:fromXDelta="10"
		android:toXDelta="300"
		android:fromYDelta="10"
		android:toYDelta="300"
	/>
</set>
           

translate動畫參數

XML節點 功能說明
translate 移動動畫

fromXDelta

toXDelta

動畫、結束起始時 X坐标上的位置

fromYDelta

toYDelta

動畫、結束起始時 Y坐标上的位置

Tween Animation共同的節點屬性

屬性[類型] 功能 備注
Duration[long] 屬性為動畫持續時間 時間以毫秒為機關
fillAfter [boolean] 當設定為true ,該動畫轉化在動畫結束後被應用
fillBefore[boolean] 當設定為true ,該動畫轉化在動畫開始前被應用
interpolator 指定一個動畫的插入器

有一些常見的插入器

accelerate_decelerate_interpolator

加速-減速 動畫插入器

accelerate_interpolator

加速-動畫插入器

decelerate_interpolator

減速- 動畫插入器

其他的屬于特定的動畫效果

repeatCount[int] 動畫的重複次數
RepeatMode[int] 定義重複的行為 1:重新開始  2:plays backward
startOffset[long] 動畫之間的時間間隔,從上次動畫停多少時間開始執行下個動畫
zAdjustment[int] 定義動畫的Z Order的改變

0:保持Z Order不變

1:保持在最上層

-1:保持在最下層

5.2其次,就是重寫View啦

TweenAnim2.java

public class TweenAnim2 extends View {
	//Alpha動畫 - 漸變透明度
	private Animation alphaAnimation = null;
	//Sacle動畫 - 漸變尺寸縮放
	private Animation scaleAnimation = null;
	//Translate動畫 - 位置移動
	private Animation translateAnimation = null;
	//Rotate動畫 - 畫面旋轉
	private Animation rotateAnimation = null;
	public TweenAnim2(Context context) {
		super(context);
		
		//初始化 Alpha動畫
		alphaAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.alpha_anim);
		//初始化 Rotate動畫
		rotateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.rotate_anim);
		//初始化 Scale動畫
		scaleAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.scale_anim);
		//初始化 Translate動畫
		translateAnimation = AnimationUtils.loadAnimation(this.getContext(), R.anim.translate_anim);
		
		//動畫集
		AnimationSet set = new AnimationSet(true);
		set.addAnimation(alphaAnimation);
		set.addAnimation(rotateAnimation);
		set.addAnimation(scaleAnimation);
		set.addAnimation(translateAnimation);
		
		//設定動畫時間 (作用到每個動畫)
		set.setDuration(5000);
		this.startAnimation(set);
	}
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		Log.e("Tween", "onDraw");
		//加載一個圖檔
		canvas.drawBitmap(((BitmapDrawable)getResources().getDrawable(R.drawable.background2)).getBitmap(), 0, 0, null);
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		Log.e("Tween", "onKeyDown");
		return true;
	}
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		Log.e("Tween", "onKeyDown");
		switch (keyCode) {
			case KeyEvent.KEYCODE_DPAD_UP:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_UP");
				break;
			case KeyEvent.KEYCODE_DPAD_DOWN:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_DOWN");
				this.startAnimation(rotateAnimation);
				break;
			case KeyEvent.KEYCODE_DPAD_LEFT:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_LEFT");
				break;
			case KeyEvent.KEYCODE_DPAD_RIGHT:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_RIGHT");
				break;
			case KeyEvent.KEYCODE_DPAD_CENTER:
				Log.e("Tween", "onKeyDown - KEYCODE_DPAD_CENTER");
				break;
			default:
				break;
		}
		return true;
	}
}
           

5.3然後,就是實作啦

FiveActivity.java

public class FiveActivity extends Activity 
{
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		TweenAnim2 anim = new TweenAnim2(FiveActivity.this);
		anim.setFocusable(true);
		setContentView(anim);
	}
}
           

5.4實作效果如圖

Android動畫之Tween動畫實作
Android動畫之Tween動畫實作
Android動畫之Tween動畫實作

做了一天的成果,希望對大家有所幫助,謝謝!

源碼下載下傳

繼續閱讀