Android utils动画

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

上一篇 下一篇

猜你喜欢

热点阅读