RotateAnimation類官方文檔:
https://developer.android.com/reference/android/view/animation/RotateAnimation.html
關於父類Animation的詳解可參考文章:
http://blog.csdn.net/ruancoder/article/details/52347243
一、RotateAnimation的使用
(1).使用xml文件創建RotateAnimation
屬性說明:
android:fromDegrees
旋轉開始角度,正數表示順時針方向,負數表示逆時針方向。
android:toDegrees
旋轉結束角度,正數表示順時針方向,負數表示逆時針方向。
android:pivotX
旋轉中心點的X座標。有三種表示方式,一是純數字,使用絕對位置(比如"50",表示以當前View左上角座標加50px作爲X座標);二是百分數,相對於控件本身定位(比如"50%",表示以當前View的左上角加上當前View寬度的50%作爲X座標);三是百分數p,相對於父控件定位(比如"50%p",表示以當前View的左上角加上父控件寬度的50%做爲X座標)。
android:pivotY
旋轉中心點的Y座標。規律同上。
示例代碼:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000">
<rotate
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360"/>
</set>
// 以view中心爲旋轉點
Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
view.startAnimation(animation);
(2).使用java代碼創建RotateAnimation
示例代碼:
// 以view左上角爲旋轉點
RotateAnimation animation = new RotateAnimation(0.0f, 360.0f);
animation.setDuration(3000);
view.startAnimation(animation);
// 以view左上角,X軸增加10px,Y軸增加50px,爲旋轉點
RotateAnimation animation = new RotateAnimation(0.0f, 360.0f, 10.0f, 50.0f);
animation.setDuration(3000);
view.startAnimation(animation);
// 以view中心爲旋轉點
RotateAnimation animation = new RotateAnimation(0.0f, 360.0f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
animation.setDuration(3000);
view.startAnimation(animation);
二、RotateAnimation的分析
RotateAnimation繼承自Animation,除了擁有父類的屬性外,添加了mFromDegrees、mToDegrees、mPivotXType、mPivotYType四個屬性。
public class RotateAnimation extends Animation {
private float mFromDegrees;
private float mToDegrees;
private int mPivotXType = ABSOLUTE;
private int mPivotYType = ABSOLUTE;
private float mPivotXValue = 0.0f;
private float mPivotYValue = 0.0f;
}
mPivotX和mPivotY最終參與動畫的計算,在ABSOLUTE類型下,mPivotXValue和mPivotYValue會賦值給mPivotX和mPivotY。
initializePivotPoint()在構造方法中被調用。
private float mPivotX;
private float mPivotY;
private void initializePivotPoint() {
if (mPivotXType == ABSOLUTE) {
mPivotX = mPivotXValue;
}
if (mPivotYType == ABSOLUTE) {
mPivotY = mPivotYValue;
}
}
使用java代碼的方式創建RotateAnimation,傳入六個參數,fromDegrees、toDegrees、pivotXType、pivotXValue、pivotYType和pivotYValue,使用如下構造方法。
參數說明:
fromDegrees:旋轉開始角度。
toDegrees:旋轉結束角度。
pivotXType:旋轉中心點的X座標類型。取值範圍爲ABSOLUTE、RELATIVE_TO_SELF、RELATIVE_TO_PARENT。
pivotXValue:旋轉中心點的X座標值。當pivotXType==ABSOLUTE時,表示絕對位置;否則表示相對位置,1.0表示100%。
pivotYType:旋轉中心點的Y座標類型,同pivotXType。
pivotYValue:旋轉中心點的Y座標值,同pivotXValue。
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
int pivotYType, float pivotYValue) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXValue = pivotXValue;
mPivotXType = pivotXType;
mPivotYValue = pivotYValue;
mPivotYType = pivotYType;
initializePivotPoint();
}
使用java代碼的方式創建RotateAnimation,傳入四個參數,fromDegrees、toDegrees、pivotX和pivotY,使用如下構造方法。
此時mPivotXType和mPivotYType默認爲ABSOLUTE。
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
使用java代碼的方式創建RotateAnimation,傳入兩個參數,fromDegrees和toDegrees,使用如下構造方法。
此時mPivotXType和mPivotYType默認爲ABSOLUTE,mPivotX和mPivotY默認爲0。
public RotateAnimation(float fromDegrees, float toDegrees) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mPivotX = 0.0f;
mPivotY = 0.0f;
}
當使用xml文件的方式創建RotateAnimation時,由AnimationUtils工具類加載動畫文件,使用如下構造方法,通過xml中的屬性來獲取值。
public RotateAnimation(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.RotateAnimation);
mFromDegrees = a.getFloat(
com.android.internal.R.styleable.RotateAnimation_fromDegrees, 0.0f);
mToDegrees = a.getFloat(com.android.internal.R.styleable.RotateAnimation_toDegrees, 0.0f);
Description d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.RotateAnimation_pivotX));
mPivotXType = d.type;
mPivotXValue = d.value;
d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.RotateAnimation_pivotY));
mPivotYType = d.type;
mPivotYValue = d.value;
a.recycle();
initializePivotPoint();
}
完成成員變量的初始化後,接下來進入動畫的計算。核心在於重寫父類Animation的initialize()和applyTransformation()方法。
initialize()方法中,根據PivotType、當前View和父View的寬高,將PivotValue轉化爲絕對位置。
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
mPivotY = resolveSize(mPivotYType, mPivotYValue, 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。通過不斷的調整degrees的值,調用Matrix的setRotate()方法,達到旋轉動畫的效果。
@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);
}
}