【问题标题】:AnimatorSet stopping when playing sequentiallyAnimatorSet 在顺序播放时停止
【发布时间】:2020-11-09 00:25:45
【问题描述】:

我有一些代码可以创建一个名为路径的点列表。

这是一个示例列表:[[1, 3], [2, 3], [2, 4]]

这是我编写的代码,用于按顺序对这些点进行动画处理:

        ArrayList<Animator> movements = new ArrayList<>();
        int prevY = start[1];
        int prevX = start[0];
        for (int[] square : path) {

            ObjectAnimator motion = new ObjectAnimator();

            float[] coord = screenFromGrid(square[0], square[1], gridSizeY);
            long speed = (long) (6000.0 / this.displayMetrics.widthPixels);
            speed = (long) (speed * getSquareSize(gridSizeY));

            if (square[0] != prevX) {

                motion = ObjectAnimator.ofFloat(this.sprite1, "x", coord[0]);
                motion.setInterpolator(new LinearInterpolator());
                motion.setDuration(speed);
                movements.add(motion);
                prevX = square[0];
            } else if (square[1] != prevY) {

                motion = ObjectAnimator.ofFloat(this.sprite1, "y", coord[1]);
                motion.setInterpolator(new LinearInterpolator());
                motion.setDuration(speed);
                movements.add(motion);
                prevY = square[1];
            }
        }
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.playSequentially(movements);
        animatorSet.start();

问题是动画在中间完全停止而没有抛出任何错误。

我检查了调试器,它说所有动画都已正确存储。

有人知道为什么会这样吗?

【问题讨论】:

    标签: java android-studio android-animation objectanimator animatorset


    【解决方案1】:

    我从经验中知道的是,AnimatorSet 有问题,并且并不总是按预期工作,我也遇到了问题,幸运的是找到了另一种更好的方法: ViewPropertyAnimator 是一种使用简短代码为视图设置动画的好方法。您可以编写自己的方法,您可以根据需要修改和重用,例如:

    private void customAnimation(View view, float toX, float toY, int duration, boolean loop) {
        view.animate()
            .translationX(toX)
            .translationY(toY)
            .setDuration(duration)
            .setInterpolator(new LinearInterpolator())
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    if(loop) {
                        customAnimation(..., false);
                    }
                }
            });
    

    侦听器等待第一个动画完成,因此您可以在那里调用下一个动画。为了顺序播放而不永远循环播放,我在参数中添加了一个布尔值,如果为真,则只执行下一个动画。

    这也会将您的其余代码缩短为这样的:

    int prevY = start[1];
    int prevX = start[0];
    for (int[] square : path) {
        float[] coord = screenFromGrid(square[0], square[1], gridSizeY);
        long speed = (long) (6000.0 / this.displayMetrics.widthPixels);
        speed = (long) (speed * getSquareSize(gridSizeY));
    
        if (square[0] != prevX) {
            customAnimation(this.sprite1, coord[0], 0, speed, true);
            prevX = square[0];
        } else if (square[1] != prevY) {
            customAnimation(this.sprite1, 0, coord[1], speed, true);
            prevY = square[1];
        }
    }
    

    请务必检查docs 以了解所有可用方法,也许.translationXBy(float byX).translationX(float toX) 更适合您的情况

    【讨论】:

    • 非常感谢!我有一个问题:您说要调用 customAnimation 两次。你的意思是这样的吗? customAnimation(...) customAnimation(...) 如果是这样,那对我不起作用,我尝试使用 withEndAction 编写递归函数,但这也不起作用。如何顺序播放?
    • sry 我按顺序误解了这个词,我更新了我的答案
    • 谢谢 :) 我有最后一个问题:这里你说的是下一个动画,但是我如何在没有递归的情况下动态循环呢?
    • 您可以在参数中添加一个布尔值,如果为真,则调用 customAnimation,否则会停止...
    • 我的意思是如何一个接一个地动态播放动画。因为在我看来,我必须对每个连续动画进行硬编码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 2023-04-05
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多