1

I have some code which creates a list of points called path.

Here is a sample list: [[1, 3], [2, 3], [2, 4]]

Here is the code I wrote to animate movement to these points sequentially:

        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();

The problem is that animation completely stops in the middle without throwing any error.

I checked the debugger and it says all the animations have been stored properly.

Does anyone know why this is happening?

KNN
  • 35
  • 5

1 Answers1

1

All I know from experience is, that AnimatorSet is buggy, and does not always work as expected, I have also had my issues with it, and luckily found another, better approach : ViewPropertyAnimator is a nice way to animate Views with short and concise code. You could write your own method which you can modify and reuse as wanted, something like :

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);
                }
            }
        });

The listener waits for the first animation to finish, so you can call the next animation there. To play sequentially without looping forever I have added a boolean to the parameters which only executes the next animation if true.

That would also shorten the rest of your code to something like this :

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];
    }
}

Be sure to check the docs for all available methods, maybe .translationXBy(float byX) is more suited in your case than .translationX(float toX)

A Honey Bustard
  • 3,433
  • 2
  • 22
  • 38
  • Thank you so much! I have one question: You said to call the customAnimation twice. Did you mean like this? `customAnimation(...)` `customAnimation(...)` If so, that didn't work for me and I tried to write a recursive function using withEndAction but that didn't work either. How do I play sequentially? – KNN Nov 10 '20 at 18:46
  • sry I misinterpretated the word sequentially, I updated my answer – A Honey Bustard Nov 10 '20 at 19:09
  • Thank you :) I have one last question: here you say next animation, but how do I loop this dynamically without a recursion? – KNN Nov 10 '20 at 20:07
  • you could add a Boolean to the parameters which if true, the customAnimation is called if not it stops... – A Honey Bustard Nov 10 '20 at 20:19
  • what I mean is how can I dynamically play the animations one after the other. Because it looks to me like I have to hard code each sequential animation. – KNN Nov 10 '20 at 20:24
  • Updated my answer, this is only one way to do it and should get you started – A Honey Bustard Nov 10 '20 at 20:49
  • Thank you so so so much! – KNN Nov 10 '20 at 20:56