javaandroidlocationandroid-animationviewpropertyanimator

Android Reset ImageView Location dynamically When Clicking on ImageView that uses Animation


I have been looking around a lot lately for setting the x and y location of an ImageView dynamically when the Image is clicked during an animation and have come up short. My ImageView starts with XML and has an animation that makes the ImageView fall towards the bottom of the screen.

When the user clicks it I want the ImageView to now go to the very top of the layout (Top of screen) and then I can choose the x location randomly. Basically so then it can keep starting at the same position and fall towards the bottom of the screen. If user clicks the ImageView then it goes back to the top so the animation can happen again.

I have an animation as such:

ViewPropertyAnimator viewPropertyAnimator = myImageView.animate()
     .translationY(bottomOfScreen)
     .setInterpolator(new AccelerateInterpolator())
     .setInterpolator(new BounceInterpolator())
     .setDuration(1000);

I have a set x and y like this inside an onClickListener for myImageView:

myImageView.setOnClickListener(new View.OnClickListener() {
    Random randomX = new Random();
    myImageView.setX(randomX.nextInt(500 - 0 + 1) + 0);
    myImageView.setY(-300);
}

The x seems to work placing the ImageView anywhere on the x I want. However it seems because of the animation occurring (dropping the ImageView towards the bottom of the Layout) when you click on the ImageView the y is always set to the position of where it was clicked.


Solution

  • First of all some things dont make sense in your code. This line :

    myImageView.setX(randomX.nextInt(500 - 0 + 1) + 0);
    

    is confusing and can be simplified to

     myImageView.setX(randomX.nextInt(500 + 1));
    

    And this line :

    myImageView.setY(-300);
    

    means you are placing the ImageView -300 of the y axis, which is off the screen. Remember that y = 0 is the top of the screen. Also it looks uncool when you just setX and setY. The views dissappear and pop up somewhere else. Why dont you try something like this :

    myImageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Random randomX = new Random();
    
                myImageView.animate()
                        .translationX(randomX.nextInt(500 + 1))
                        .translationY(myImageView.getHeight())
                        .setInterpolator(new AccelerateDecelerateInterpolator())
                        .setDuration(500)
                        .setListener(new Animator.AnimatorListener() {
                            @Override
                            public void onAnimationStart(Animator animation) {
    
                            }
    
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                myImageView.animate()
                                        .translationY(bottomOfScreen)
                                        .setInterpolator(new AccelerateInterpolator())
                                        .setInterpolator(new BounceInterpolator())
                                        .setDuration(1000);
                            }
    
                            @Override
                            public void onAnimationCancel(Animator animation) {
    
                            }
    
                            @Override
                            public void onAnimationRepeat(Animator animation) {
    
                            }
                        });
            }
        });
    

    This animates the View back to the top and waits until the Animation has finished thanks to the AnimatorListener and then lets it drop again when onAnimationEnd() is called.