本文摘自博友野狗道人,博文地址:https://www.cnblogs.com/glimpse/p/5256182.html
介紹:
補間動畫是一種設定動畫開始狀態、結束狀態,其中間的變化由系統計算補充。這也是他叫做補間動畫的原因。
補間動畫由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();
}
}