Android 移动View到指定View的位置动画
2021-08-12 本文已影响0人
清朝公主大清正黄旗
第一种:
private void moveViewToTargetView(View view, View targetView) {
final float x = view.getX();
final float y = view.getY();
final float targetX = targetView.getX();
final float targetY = targetView.getY();
view.animate()
.translationX(-(x - targetX))
.translationY(-(y- targetY))
.setDuration(800)
.setInterpolator(new DecelerateInterpolator())
.withLayer()
.start();
moveToWord(view, targetView);
}
上面的两个View的 x 和 y 都是指定view的左上角的x,y轴坐标
DecelerateInterpolator: 是以先加速在减速的方式
直接copy代码,传递两个View的对象就可以使用了。
如果想要监听动画,通过view.getAnimation().setAnimationListener 在设置监听
第二种(复杂点):
private void moveToWord(View view, View targetView) {
final float x = view.getX();
final float y = view.getY();
final float targetX = targetView.getX();
final float targetY = targetView.getY();
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(600);
valueAnimator.setObjectValues(new PointF(x, y));
valueAnimator.setInterpolator(new DecelerateInterpolator());
//首先判断 目标点在上还是在下
final boolean flagX = ((x - targetX) > 0) ? true : false;
final boolean flagY = ((y - targetY) > 0) ? true : false;
valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF startValue,
PointF endValue) {
//从0.0 --->> 1.0
PointF point = new PointF();
//这里是需要倒着来 最后要到达200 200 这个点
float fractionNeed = 1 - fraction;
if (flagX) {
float vX = x - targetX;
point.x = vX * fractionNeed + targetX;
} else {
float vX = targetX - x;
point.x = x + vX * fraction;
}
if (flagY) {
float vY = y - targetY;
point.y = vY * fractionNeed + targetY;
} else {
float vY = targetY - y;
point.y = y + vY * fraction;
}
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
PointF point = (PointF) animation.getAnimatedValue();
float vX = point.x;
float vY = point.y;
//说明vx 最大值就是view原坐标
if (flagX) {
if (vX <= x && vX >= targetX) {
view.setX(vX);
}
} else {//说明vx 最小值就是view原坐标
if (vX >= x && vX <= targetX) {
view.setX(vX);
}
}
//说明vY 最大值就是view原坐标
if (flagY) {
if (vY <= y && vY >= targetY) {
view.setY(vY);
}
} else {//说明vx 最小值就是view原坐标
if (vY >= y && vY <= targetY) {
view.setY(vY);
}
}
}
});
}
这是第二种实现方式,跟第一种相比,代码量上多了不少,第一种实现方式有个很有趣的现象,如果你设置点击事件后,开始移动到指定View,,如果在移动后的终点位置,你在点击那个View,它会自动回到起始位置,第二种实现方式是不行的。
以上两种方式都可以直接copy代码使用
本文参考原文地址:https://blog.csdn.net/FlyPig_Vip/article/details/98070578