Android 各類動畫的使用方法

Android的動畫有三類:

1,補間動畫。2,幀動畫。3,屬性動畫



這裏的實現主要是做補間動畫和屬性動畫的實現



補間動畫:
補間動畫有四種:
ScaleAnimation(大小縮放,X、Y軸縮放,還包括縮放中心pivotX、pivotY)
TranslationAnimation(位移,X、Y軸位移)

RotateAnimation(旋轉,包括縮放中心pivotX、pivotY)

AlphaAnimation(透明度(alpha)漸變效果)


補間動畫屬性動畫最大的區別就是:補間動畫是不會改變view的屬性,只是在視覺上進行動畫效果。

舉個例子:

一個button初始位置在(0,0),通過補間動畫的TranslationAnimation領他移動到(5,5),在這整個過程中,這個button的有效點擊區域都是(0,0),不會因爲動畫位置移動而發生改變。


補間動畫的用法:
1,xml構建:
在anim目錄下新建一個XML文件

<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0"
    android:toYDelta="100"
    android:repeatMode="reverse"
    android:repeatCount="-1"
    android:duration="1000">
    

</translate>
上面的代碼設置了view的Y座標從0移動到100,時間是1秒

其中有兩個屬性:

repeatCount:設置動畫播放的次數,當值爲-1時,永遠執行

repeatMode:設置動畫重複播放的模式

restart:普通的循環播放,一次動畫部分完成後會直接回到初始位置開始播放(中間沒有動畫)

resverse:當動畫播放的次數是偶數次或者永遠循環播放時,會有反向效果(在一次動畫播放完成後,會以動畫的形式反向回到初始位置)


在設置好xml文件後再代碼中:

		    Animation translateY = AnimationUtils.loadAnimation(this, R.anim.translate_y);
		    mBlueBall.startAnimation(translateY);

mBlueBall是一個imageView,任何一個View的之類都能使用這個方法。




2,代碼構建補間動畫:
		/*
		 * android.view.animation.TranslateAnimation.TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
		 * */
		 TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
		    animation.setDuration(1000);
		    animation.setFillAfter(true);
		    animation.setInterpolator(new AccelerateInterpolator());
		    mBlueBall.startAnimation(animation);

上面的代碼設置了view的X座標從0移動到200,時間是1秒

其中animation.setFillAfter(true);是設置動畫播放完成後是否返回初始位置。

animation.setInterpolator(new AccelerateInterpolator());是設置動畫播放速度的類型,主要有8種

LinearInterpolator(勻速)
AccelerateInterpolator(先慢後快)
AccelerateDecelerateInterpolator(先慢中快後慢)
DecelerateInterpolator(先快後慢)
CycleInterpolator(循環播放,速度爲正弦曲線)
AnticipateInterpolator(先回撤,再勻速向前)
OvershootInterpolator(超過,拉回)
BounceInterpolator(回彈)


同樣地,XML的屬性也能在代碼中設置,這就不一一舉例。

主要詳細記錄是的屬性動畫的使用。

屬性動畫有4種使用創建方式:
1,ObjectAnimator

2,ValueAnimator

3.AnimatorInflater(XML定義創建)

4,View.animate();

ObjectAnimator:

ObjeckAnimator是這麼多個方式中相對比較容易實現的

ObjectAnimator anim2 = ObjectAnimator
	 .ofFloat(view, "alpha", 1.0f, 0.75f, 0.5f, 0.25f, 0.15f, 0.0f)//
	 .setDuration(5000);
	 anim2.setInterpolator(new LinearInterpolator());
	 anim2.start();

這是定義View的透明值從不透明到完全透明的過程,過程是5秒,其中

ObjectAnimator android.animation.ObjectAnimator.ofFloat(Object view, String propertyName, float... values)

view:是需要動畫的view實體

propertyName:動畫需要變化的屬性的名稱,這個名稱需要在view中有getter和setter纔有效。

values:後面的數值數量是不確定的最少一個,當參數只有一個的時候,就認爲動畫變化屬性的最終值是value,初始值是view.getter的值,當values的數量是兩個時,就認爲第一個是初始值,最後一個是最終值,如此類推。


anim2.setInterpolator(new LinearInterpolator());跟補間動畫一樣,是設置動畫播放的速度方式。


ObjectAnimator還有一種用法:

ObjectAnimator anim = ObjectAnimator
				.ofFloat(view, "scaleDisplay", 1.0F,  0.2F)
				.setDuration(500);
		anim.start();
		
		anim.addUpdateListener(new AnimatorUpdateListener()
		{
			@Override
			public void onAnimationUpdate(ValueAnimator animation)
			{
				float value = (Float) animation.getAnimatedValue();
				view.setAlpha(value);
				view.setScaleX(value);
				view.setScaleY(value);
			}
		});

ofFloatpropertyName設置一個自定義的屬性名,這樣正常來說因爲view中沒有對應的getter,所以動畫是無效的。但是當我們添加一個UpdateListener後。就可以在listener中做對應的屬性變化。這樣也可以做到同樣的效果。

onAnimationUpdate函數是動畫每一段時間(貌似是10毫秒)都會調用的,

在這裏獲取每一幀傳入的變化值(ValueAnimator.getAnimatedValue()),用來設置對應的屬性變化。

這樣只要一個ObjectAnimator就可以做到AnimatorSet.playTogether()的效果,唯一一點的不同是,因爲屬性變化的值都是同一個,所以所有屬性變化的速率都是一樣的。如果需要不用速率變化多個屬性,還是需要使用AnimatorSet


ValueAnimator的用法跟ObjectAnimator差不多,不同的是ValueAnimator在設置的時候不需要定義變化的屬性,而是在中設置

ValueAnimator animator = ValueAnimator.ofFloat(0, 400);
		//稍微實現了一下,在不設置作用對象的情況下,一樣可以對mBlueBall進行動畫
		animator.setTarget(mBlueBall);
		animator.setDuration(1000).start();
		animator.addUpdateListener(new AnimatorUpdateListener()
		{
			@Override
			public void onAnimationUpdate(ValueAnimator animation)
			{
				mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
			}
		});

然而,ValueAnimator還可以做一些相對複雜的動畫,通過設置

void android.animation.ValueAnimator.setEvaluator(TypeEvaluator value)

TypeEvaluator值是一個泛型,可以根據自己的需求定義一個類型或者傳入一個map類型。

ValueAnimator valueAnimator = new ValueAnimator();
		valueAnimator.setDuration(3000);
		
		valueAnimator.setObjectValues(new HashMap<String, Object>());
		valueAnimator.setInterpolator(new LinearInterpolator());
		valueAnimator.setEvaluator(new TypeEvaluator<Map<String, Object>>()
		{
			// fraction = t / duration
			@Override
			public Map evaluate(float fraction, Map startValue,
					Map endValue)
			{
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("x", 200 * fraction * 3);
				map.put("y", 0.5f * 100 * (fraction * 3) * (fraction * 3));
				return map;
			}
		});
		
		
		valueAnimator.addUpdateListener(new AnimatorUpdateListener()
		{
			@Override
			public void onAnimationUpdate(ValueAnimator animation)
			{
				Map<String, Object> map = (Map<String, Object>) animation.getAnimatedValue();
				//float x = (Float) map.get("x");
				mBlueBall.setX((Float)map.get("x"));
				mBlueBall.setY((Float)map.get("y"));

			}
		});
		valueAnimator.start();

基本流程是在Evaluator中定義好泛型的值然後再updateListener中獲取做對應的屬性變化處理。


AnimatorInflater(XML定義創建):這個的用法和補間動畫中的xml創建一樣 

首先設置xml文件:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together" >

    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>
    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>

</set>

在set便籤中的ordering屬性:together同一時間播放動畫,sequentially表示順序執行

然後在代碼中獲取:

// 加載動畫
		Animator anim = AnimatorInflater.loadAnimator(this, R.animator.scale);
		mMv.setPivotX(0);
		mMv.setPivotY(0);
		//顯示的調用invalidate
		mMv.invalidate();
		anim.setTarget(mMv);
		anim.start();

這裏因爲手動設置了view的prvotX屬性。所以要手動調用一下invalidate();






PS:參考博客:Android 屬性動畫(Property Animation) 完全解析 (上)

http://blog.csdn.net/lmj623565791/article/details/38067475




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章