最近需求要做一個小球上升再下降的抛物線運動,類似太陽東升西落的動畫。
在網上找了好久,好多的抛物線都是平抛,用于購物車添加效果。
于是自己動手,做了一個完整的向上抛物線的動畫。
首先要區分兩個概念,一個是VIew的坐标系,如下圖(來自網絡)

另外一個就是Animation動畫的坐标,最開始,我以為動畫是在View坐标系上進行的。研究之後才發現,Animation有自己的坐标,跟View的坐标沒有關系。如下(圖檔來源于網絡),動畫的坐标原點是VIew動畫開始的起點(左上角)
是以要實作完整的抛物線運動,首先要通過計算,算出抛物線的起點、頂點、終點。通過設定動畫參數就可以了
首先确定抛物線的原點(TextView的中心),然後在通過對這個坐标在X軸Y軸上加減得到起點。頂點、終點。
private void initLocation(TextView textView) {
//擷取抛物線原點坐标
int[] point_location = new int[2];
textView.getLocationInWindow(point_location);
int pointX = point_location[0] - textView.getWidth() / 2;
int pointY = point_location[1] - textView.getHeight() / 2;
//擷取抛物線起點坐标
startX = pointX - 500;
startY = pointY;
//擷取抛物線頂點坐标
topX = pointX;
topY = pointY - 800;
//擷取抛物線終點坐标
endX = pointX + 500;
endY = pointY;
}
最後就可以做動畫啦,動畫分為上升和下降兩個部分
/**
* 抛物線 上升動畫
*/
@TargetApi(11)
public void playUpAnimation() {
initLocation(tvPoint);
moveingIV = (ImageView) getLayoutInflater().inflate(R.layout.animator_image, null);
anim_mask_layout.addView(moveingIV);//把動畫圖檔添加到動畫層
addViewToAnimLayout(moveingIV, startX, startY);
//抛物線動畫,原理:兩個位移動畫,一個橫向勻速移動,一個縱向變速移動,兩個動畫同時執行,就有了抛物線的效果。
ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(moveingIV, "translationX", 0, topX - startX);
translateAnimationX.setDuration(800);
translateAnimationX.setInterpolator(new AccelerateInterpolator());
ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(moveingIV, "translationY", 0, topY - startY);
translateAnimationY.setDuration(800);
translateAnimationY.setInterpolator(new LinearInterpolator());
AnimatorSet animatorSet = new AnimatorSet();//設定動畫播放順序
animatorSet.play(translateAnimationX).with(translateAnimationY);
animatorSet.start();
}
/**
* 抛物線 下降動畫
*/
@TargetApi(11)
public void playDownAnimation() {
//抛物線動畫,原理:兩個位移動畫,一個橫向勻速移動,一個縱向變速移動,兩個動畫同時執行,就有了抛物線的效果。
ObjectAnimator translateAnimationX = ObjectAnimator.ofFloat(moveingIV, "translationX", topX - startX, endX - startX);
translateAnimationX.setDuration(800);
translateAnimationX.setInterpolator(new LinearInterpolator());
ObjectAnimator translateAnimationY = ObjectAnimator.ofFloat(moveingIV, "translationY", topY - startY, 0);
translateAnimationY.setDuration(800);
translateAnimationY.setInterpolator(new AccelerateInterpolator());
AnimatorSet animatorSet = new AnimatorSet();//設定動畫播放順序
animatorSet.play(translateAnimationX).with(translateAnimationY);
translateAnimationY.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
anim_mask_layout.removeView(moveingIV); //動畫結束後移除動畫圖檔
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();
}
完整DEMO
https://download.csdn.net/download/y280903468/11970396