介紹:
補間動畫是一種設定動畫開始狀態、結束狀態,其中間的變化由系統計算補充。這也是他叫做補間動畫的原因。
補間動畫由Animation類來實現具體效果,包括平移(TranslateAnimation)、縮放(ScaleAnimation)、旋轉(RotateAnimation)、透明度(AlphaAnimation)四個子類,四種變化。
實現:
補間動畫的四種變化效果(四個類)允許通過xml設置,也可以通過初始化類來設置。xml比較簡單,java比較靈活。
1、通過xml設置補間動畫
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
android:interpolator為動畫的變化速度【可以單獨設置,可以直接放在set里面】
可以設置多種速度變化方式,這里只列出勻速、加速、減速
勻速 @android:anim/linear_interpolator
加速 @android:anim/accelerate_interppolator
減速 @android:anim/decelerate_interpolator
android:shareInterpolator為是否給所有子元素共享動畫變化速度【放在set里面設置是否共享】
android:fillAfter動畫顯示結束保持最后一幀【true:最后一幀】
android:fillBefore動畫顯示結束保持第一幀【true:第一幀】
android:duration動畫播放時間【單位毫秒,每個動畫都需要設置,否則沒有效果】
android:startOffset動畫裝載完成后需要等待多少時間才能啟動【單位毫秒】
透明度
android:fromAlpha為動畫開始的透明度【0:完全透明,1:完全不透明】
android:toAlpha為動畫結束的透明度
縮放
android:fromXScale、android:fromYScale為動畫開始X,Y方向上的縮放比例【0:小的沒有,1:原本大小】
android:toXScale、android:toYScale為動畫開始X,Y方向上的縮放比例
android:pivotX、android:pivotY為動畫在X,Y方向上的縮放中心點(比如設置為0,0那么就是寬和高向左上角縮小)【例如:50%是距左邊界圖片一半的距離】
平移
android:fromXDelta、android:fromYDelta為動畫平移的起始點
android:toXDelta、android:toYDelta為動畫平移的結束點
旋轉
android:fromDegrees為動畫旋轉的起始角度【0:不動,180:轉半圈,360:轉一圈,3600:轉10圈,-180逆時針轉半圈】
android:toDegrees為動畫旋轉的結束角度
android:pivotX、android:pivotY為動畫旋轉的中心點【例如:50%是距左邊界圖片一半的距離】
以上每一個都可以在java代碼中通過setXXX來設置。
通過xml新建完動畫資源還需要使用AnimationUtils進行裝載。
final Animation anim = AnimationUtils .loadAnimation(this, R.anim.anim);
上面的R.anim.anim就是上面用xml寫出來的動畫文件。
其實補間動畫是一種View Animation,是專門作用在View上的。
所以在我們使用的時候,直接調用View的startAnimation方法就好了。
flower.startAnimation(reverse);
代碼中的flower是一個ImageView。
2、除了使用xml定義動畫以外,還可以直接新建一個相應的對象。
新建對象時構造函數的參數和上面的xml是一樣的,就不詳細介紹了~
平移(TranslateAnimation)
構造函數
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)
fromXType、toXType、fromYType、toYType指的是坐標類型,默認為ABSOLUTE,如果使用絕對坐標的話可以省去type這個參數。基本上使用這個參數都是為了設置為RELATIVE_TO_SELF,意思是相對有自己的距離。
剩下的那些值就好xml里一樣,自己就能看懂啦~
下面是具體的使用:
TranslateAnimation translateAnimation =
new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0f,
Animation.RELATIVE_TO_SELF, 0.5f
);
translateAnimation.setDuration(5000);
image.startAnimation(translateAnimation);
縮放(ScaleAnimation)
構造函數:
public ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
pivotXType、pivotYType指的是坐標類型,默認為ABSOLUTE,如果使用絕對坐標的話可以省去type這個參數。基本上使用這個參數都是為了設置為RELATIVE_TO_SELF,意思是相對有自己的距離。
下面是具體的使用:
ScaleAnimation scaleAnimation = new ScaleAnimation( 0, 1f, 0, 1f, Animation.RELATIVE_TO_SELF,0.5f); scaleAnimation.setDuration(5000); image.startAnimation(scaleAnimation);
旋轉(RotateAnimation)
構造函數:
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
pivotXType、pivotYType指的是坐標類型,默認為ABSOLUTE,如果使用絕對坐標的話可以省去type這個參數。基本上使用這個參數都是為了設置為RELATIVE_TO_SELF,意思是相對有自己的距離。
具體使用:
RotateAnimation rotateAnimation = new RotateAnimation( 0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5F); rotateAnimation.setDuration(1000); image.startAnimation(rotateAnimation);
透明度(AlphaAnimation)
構造函數:
public AlphaAnimation(float fromAlpha, float toAlpha)
具體使用:
AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0); alphaAnimation.setDuration(5000); image.startAnimation(alphaAnimation);
Animation類介紹
既然補間動畫的四種變化都是基於Animation寫的,那么我們是不是也可以自定義一個補間動畫呢。
當然可以。
其實Animation類最主要的函數是applyTransformation,重寫這個函數就可以實現自己的動畫啦~
protected void applyTransformation(float interpolatedTime, Transformation t)
interpolatedTime:代表動畫的時間進行比,不管實際持續時間是多少,當動畫播放時,該參數總是從0到1
Transformation :這個參數是補間動畫在不同時刻的變化,具體的變化都是通過這個參數實現。這個對象里面封裝了一個Matrix,所以可以直接使用Matrix的函數實現對View的各種操作。
干說也不明白,我們直接看一下RotateAnimation的代碼吧~
@Override protected void applyTransformation(float interpolatedTime, Transformation t) { float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime); float scale = getScaleFactor(); if (mPivotX == 0.0f && mPivotY == 0.0f) { t.getMatrix().setRotate(degrees); } else { t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale); } }
這個函數可能是能夠不斷的裝載吧(這他媽做么做到的,誰知道的話在評論里告訴我!!),在不同的時間通過運算就能夠得到不同的角度,然后設置相應的旋轉角度。
由於Matrix提供傾斜函數,我們可以寫一個傾斜的動畫。雖然可能沒有什么實際用處。
代碼貼在下面,我就這么隨便一寫,更多玩法等待你的開發哦~
package activity; import android.view.animation.Animation; import android.view.animation.Transformation; public class MyAnimation extends Animation{ private float mkx; private float mky; public MyAnimation(float kx, float ky) { this.mkx = kx; this.mky = ky; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { float kx = mkx * interpolatedTime; float ky = mky * interpolatedTime; t.getMatrix().setSkew(kx, ky); } }
我在學習安卓時的教材用的是《安卓瘋狂講義》,他在這里講了控制三維變換的類Camera,也可以使用這個類來實現動畫三維變換。
關於這個類的具體信息大家可以看一下官網:http://developer.android.com/reference/android/graphics/Camera.html
常用的幾個函數列一下:
getMatrix(Matrix matrix):將Camera所做的變換用用到matrix上
rotate(float x, float y, float z):三個方向上的變換
rotateX(float deg):將目標組件沿X軸旋轉
rotateY(float deg):將目標組件沿Y軸旋轉
rotateZ(float deg):將目標組件沿Z軸旋轉
translate(float x,float y,float z):把目標組件在三維空間內進行位移變換
applyToCanvas(Canvas canvas):把Camera所做變幻應用到Canvas上
save():保存Camera的狀態
。。。
然后大家就看一下我這本書上他們自定義的動畫吧~
public class MyAnimation extends Animation { private float centerX; private float centerY; // 定義動畫的持續事件 private int duration; private Camera camera = new Camera(); public MyAnimation(float x, float y, int duration) { this.centerX = x; this.centerY = y; this.duration = duration; } @Override public void initialize(int width, int height , int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); // 設置動畫的持續時間 setDuration(duration); // 設置動畫結束后效果保留 setFillAfter(true); setInterpolator(new LinearInterpolator()); } /* * 該方法的interpolatedTime代表了抽象的動畫持續時間,不管動畫實際持續時間多長, * interpolatedTime參數總是從0(動畫開始時)~1(動畫結束時) * Transformation參數代表了對目標組件所做的變. */ @Override protected void applyTransformation(float interpolatedTime , Transformation t) { camera.save(); // 根據interpolatedTime時間來控制X、Y、Z上的偏移 camera.translate(100.0f - 100.0f * interpolatedTime, 150.0f * interpolatedTime - 150, 80.0f - 80.0f * interpolatedTime); // 設置根據interpolatedTime時間在Y柚上旋轉不同角度。 camera.rotateY(360 * (interpolatedTime)); // 設置根據interpolatedTime時間在X柚上旋轉不同角度 camera.rotateX((360 * interpolatedTime)); // 獲取Transformation參數的Matrix對象 Matrix matrix = t.getMatrix(); camera.getMatrix(matrix); matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); camera.restore(); } }
