做項目的時候,需要用到動畫掀鹅,大小和位置都不一樣散休。剛開始想到的是ScaleAnimation和TranslateAnimation進行組合,但實驗后發(fā)現(xiàn)乐尊,目標位置始終不對戚丸,只用TranslateAnimation是沒有問題,所以ScaleAnimation應該不只是進行了縮放
經(jīng)過查找資料扔嵌,發(fā)現(xiàn)ScaleAnimation還進行起始位置的移動限府。ScaleAnimation分為兩種情況,從本身的位置縮放到另一個位置和從另一個位置縮放到本身的位置
先看一下處理后的效果
看一下ScaleAnimation的構(gòu)造函數(shù)
/**
* fromX 在x軸方向痢缎,起始縮放比例
* toX 在x軸上胁勺,目標縮放比例
* fromY 在y軸方向,起始縮放比例
* toY 在y軸上独旷,目標縮放比例
* pivotX 縮放的中心軸位置署穗,這個跟我們自己的理解不一樣,要通過算法算出來嵌洼,這兩種情況的算法還不一樣
* pivotY
*/
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
float pivotX, float pivotY) {
mResources = null;
mFromX = fromX;
mToX = toX;
mFromY = fromY;
mToY = toY;
mPivotXType = ABSOLUTE;
mPivotYType = ABSOLUTE;
mPivotXValue = pivotX;
mPivotYValue = pivotY;
initializePivotPoint();
}
fromX, toX, fromY, toY這4個參數(shù)很好理解案疲,我們重點看一下pivotX,pivotY是怎么計算的
- 從本身的位置縮放到另一個位置
這種情況下麻养,我們關(guān)心的是縮放后的目標位置褐啡,這里有幾個值需要先了解一些,目標view的右邊(targetRight)鳖昌,初始view左邊的距離(sourceLeft)备畦,pivotX,初始view的寬(sourceWidth)许昨,放大的值(toX)懂盐,他們的關(guān)系如下
targetRight - sourceLeft = pivotX - (pivotX - sourceWidth) * toX,那么pivotX的值是pivotX = (targetRight - sourceLeft - sourceWidth * toX) / (1 - toX)
pivotY的值類似糕档,就不在描述了允粤。
- 從另一個位置縮放到本身的位置
這種情況我們關(guān)心的是開始的位置,它們的關(guān)系是sourceLeft - targetLeft = pivotX * (1 - scaleX),那么pivotX = (sourceLeft - targetLeft) / (1 - fromX)
理清楚這個后类垫,動畫效果有縮放和移動的,只需要一個ScaleAnimation就能完成琅坡。為了方便后期使用寫了一個幫助類
public class TranslateAnimHelper {
public static Animation tanslateScaleAnim(boolean fromOrigin, Rect sourceRect, Rect targetRect){
Animation anim = null;
float sx = targetRect.width() * 1.0f / sourceRect.width();
float sy = targetRect.height() * 1.0f / sourceRect.height();
boolean isScale = sx != 1 || sy != 1;
if(isScale){
anim = scaleAnim(fromOrigin, sourceRect, targetRect);
}else{
if(fromOrigin){
int fromDeltaX = 0;
int toDeltaX = targetRect.left - sourceRect.left;
int fromDeltaY = 0;
int toDeltaY = targetRect.top - sourceRect.top;
anim = new TranslateAnimation(fromDeltaX, toDeltaX, fromDeltaY, toDeltaY);
}else {
int fromDeltaX = -(targetRect.left - sourceRect.left);
int toDeltaX = 0;
int fromDeltaY = -(targetRect.top - sourceRect.top);
int toDeltaY = 0;
anim = new TranslateAnimation(fromDeltaX, toDeltaX, fromDeltaY, toDeltaY);
}
}
return anim;
}
public static Animation scaleAnim(boolean fromOrigin, Rect sourceRect, Rect targetRect){
float sx = targetRect.width() * 1.0f / sourceRect.width();
float sy = targetRect.height() * 1.0f / sourceRect.height();
Animation animation = null;
if(fromOrigin){
float fromX = 1;
float toX = sx;
float fromY = 1;
float toY = sy;
float px = (targetRect.right - sourceRect.left - sourceRect.width() * sx) / (1 - toX);
float py = (targetRect.bottom - sourceRect.top - sourceRect.height() * sy) / (1 - toY);
animation = new ScaleAnimation(fromX, toX, fromY, toY, px, py);
}else{
float fromX = 1 / sx;
float toX = 1;
float fromY = 1 / sy;
float toY = 1;
float px = (sourceRect.left - targetRect.left) / (1 - fromX);
float py = (sourceRect.top - targetRect.top) / (1 - fromY);
animation = new ScaleAnimation(fromX, toX, fromY, toY, px, py);
}
return animation;
}
}