1,補間動畫。2,幀動畫。3,屬性動畫
這裏的實現主要是做補間動畫和屬性動畫的實現
補間動畫有四種:
ScaleAnimation(大小縮放,X、Y軸縮放,還包括縮放中心pivotX、pivotY)
TranslationAnimation(位移,X、Y軸位移)
RotateAnimation(旋轉,包括縮放中心pivotX、pivotY)
AlphaAnimation(透明度(alpha)漸變效果)
舉個例子:
一個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的之類都能使用這個方法。
/*
* 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(回彈)
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);
}
});
在ofFloat中propertyName設置一個自定義的屬性名,這樣正常來說因爲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還可以做一些相對複雜的動畫,通過設置
而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