TranslateAnimation類官方文檔:
https://developer.android.com/reference/android/view/animation/TranslateAnimation.html
關於父類Animation的詳解可參考文章:
http://blog.csdn.net/ruancoder/article/details/52347243
一、TranslateAnimation的使用
(1).使用xml文件創建TranslateAnimation
屬性說明:
android:fromXDelta:動畫開始點的X軸座標。有三種表示方式,一是純數字,使用絕對位置(比如"50",表示以當前View左上角座標加50px作爲X座標);二是百分數,相對於控件本身定位(比如"50%",表示以當前View的左上角加上當前View寬度的50%作爲X座標);三是百分數p,相對於父控件定位(比如"50%p",表示以當前View的左上角加上父控件寬度的50%做爲X座標)。
android:fromYDelta:動畫開始點的Y軸座標。
android:toXDelta:動畫結束點的X軸座標。
android:toYDelta:動畫結束點的Y軸座標。
示例代碼:
從屏幕底部進入的動畫。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
<translate
android:fromYDelta="100%p"
android:toYDelta="0.0"/>
</set>
從屏幕左側退出的動畫。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
<translate
android:fromXDelta="0.0"
android:toXDelta="-100%p"/>
</set>
(2).使用java代碼創建TranslateAnimation
示例代碼:
//從當前位置,向下和向右各平移300px
TranslateAnimation animation = new TranslateAnimation(0.0f, 300.0f, 0.0f, 300.0f);
animation.setDuration(3000);
view.startAnimation(animation);
// 從屏幕底部進入的動畫
TranslateAnimation animation = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 1.0f, Animation.RELATIVE_TO_PARENT, 0.0f
);
animation.setDuration(3000);
view.startAnimation(animation);
二、TranslateAnimation的分析
TranslateAnimation繼承自Animation,除了擁有父類的屬性外,添加了mFromXType、mToXType、mFromYType、mToYType和mFromXValue、mToXValue、mFromYValue、mToYValue八個屬性。這個八個屬性可以通過構造方法或xml屬性傳入,最終由mFromXDelta、mToXDelta、mFromYDelta和mToYDelta參與動畫的計算。
public class TranslateAnimation extends Animation {
private int mFromXType = ABSOLUTE;
private int mToXType = ABSOLUTE;
private int mFromYType = ABSOLUTE;
private int mToYType = ABSOLUTE;
protected float mFromXValue = 0.0f;
protected float mToXValue = 0.0f;
protected float mFromYValue = 0.0f;
protected float mToYValue = 0.0f;
protected float mFromXDelta;
protected float mToXDelta;
protected float mFromYDelta;
protected float mToYDelta;
}
使用java代碼的方式創建TranslateAnimation,傳入六個參數,fromXType、fromXValue、toXType、toXValue和fromYType、fromYValue、toYType、toYValue,使用如下構造方法。
參數說明:
fromXType:動畫開始前的X座標類型。取值範圍爲ABSOLUTE(絕對位置)、RELATIVE_TO_SELF(以自身寬或高爲參考)、RELATIVE_TO_PARENT(以父控件寬或高爲參考)。
fromXValue:動畫開始前的X座標值。當對應的Type爲ABSOLUTE時,表示絕對位置;否則表示相對位置,1.0表示100%。
toXType:動畫結束後的X座標類型。
toXValue:動畫結束後的X座標值。
fromYType:動畫開始前的Y座標類型。
fromYValue:動畫開始前的Y座標值。
toYType:動畫結束後的Y座標類型。
toYValue:動畫結束後的Y座標值。
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue) {
mFromXValue = fromXValue;
mToXValue = toXValue;
mFromYValue = fromYValue;
mToYValue = toYValue;
mFromXType = fromXType;
mToXType = toXType;
mFromYType = fromYType;
mToYType = toYType;
}
使用java代碼的方式創建TranslateAnimation,傳入四個參數,fromXDelta、toXDelta、fromYDelta和toYDelta,使用如下構造方法。
此時mFromXType、mToXType、mFromYType和mToYType默認爲ABSOLUTE。
參數說明:
fromXDelta:動畫開始前,離當前View X座標上的距離。
toXDelta:動畫結束後,離當前View X座標上的距離。
fromYDelta:動畫開始前,離當前View Y座標上的距離。
toYDelta:動畫結束後,離當前View Y座標上的距離。
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
mFromXValue = fromXDelta;
mToXValue = toXDelta;
mFromYValue = fromYDelta;
mToYValue = toYDelta;
mFromXType = ABSOLUTE;
mToXType = ABSOLUTE;
mFromYType = ABSOLUTE;
mToYType = ABSOLUTE;
}
當使用xml文件的方式創建TranslateAnimation時,由AnimationUtils工具類加載動畫文件,使用如下構造方法,通過xml中的屬性來獲取值。
public TranslateAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.TranslateAnimation);
Animation.Description d = Animation.Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_fromXDelta));
mFromXType = d.type;
mFromXValue = d.value;
d = Animation.Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_toXDelta));
mToXType = d.type;
mToXValue = d.value;
d = Animation.Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_fromYDelta));
mFromYType = d.type;
mFromYValue = d.value;
d = Animation.Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_toYDelta));
mToYType = d.type;
mToYValue = d.value;
a.recycle();
}
完成成員變量的初始化後,接下來進入動畫的計算。核心在於重寫父類Animation的initialize()和applyTransformation()方法。
initialize()方法中,根據上面傳入的八個屬性值,結合當前View和父View的寬高,計算出平移的絕對位置。
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mFromXDelta = resolveSize(mFromXType, mFromXValue, width, parentWidth);
mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);
}
protected float resolveSize(int type, float value, int size, int parentSize) {
switch (type) {
case ABSOLUTE:
return value;
case RELATIVE_TO_SELF:
return size * value;
case RELATIVE_TO_PARENT:
return parentSize * value;
default:
return value;
}
}
applyTransformation()方法負責動畫的執行。在動畫從開始倒結束的過程中,參數interpolatedTime從0.0遞增到1.0。通過不斷的調整dx和dy的值,調用Matrix的setTranslate()方法,達到平移View的效果。
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = mFromXDelta;
float dy = mFromYDelta;
if (mFromXDelta != mToXDelta) {
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
}
if (mFromYDelta != mToYDelta) {
dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
}
t.getMatrix().setTranslate(dx, dy);
}