27

I have several ImageViews in a RelativeLayout.

When the user taps any of the ImageViews, I want the ImageView to be moved to a specified location using a subtle animation.

Eg; I have initially set margins for LayoutParams associated with an ImageView as layoutparams1.setMargins(90,70,0,0); and I have then added it to the layout.

When the ImageView is tapped, I'd like its new location to be 200,200, done with animation.

So, is it possible? if yes, then how?

Note that I have both RelativeLayout and all of its child ImageViews created programmatically.

And I'm new to Android development so an elaborative answer is expected.

Ola Ström
  • 4,136
  • 5
  • 22
  • 41
Kushal
  • 3,112
  • 10
  • 50
  • 79

5 Answers5

56
TranslateAnimation animation = new TranslateAnimation(0, 50, 0, 100);
animation.setDuration(1000);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener());

imageView.startAnimation(animation);

UPDATE : The problem is that the View is actually still in it's old position. So we have to move it when the animation is finished. To detect when the animation is finished we have to create our own animationListener (inside our activity class):

private class MyAnimationListener implements AnimationListener{

    @Override
    public void onAnimationEnd(Animation animation) {
        imageView.clearAnimation();
        LayoutParams lp = new LayoutParams(imageView.getWidth(), imageView.getHeight());
        lp.setMargins(50, 100, 0, 0);
        imageView.setLayoutParams(lp);
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    @Override
    public void onAnimationStart(Animation animation) {
    }

}

So the onClickEvent will get fired again at it's new place. The animation will now move it even more down, so you might want to save the x and y in a variable, so that in the onAnimationEnd() you move it not to a fix location.

Recomer
  • 178
  • 2
  • 12
D-32
  • 3,245
  • 2
  • 22
  • 33
  • 2
    Works!! but at new position of ImageView, it doesn't respond to any tap events, and also, if I click to its previous location, another instance of same imageview animates. Any way to fix it? – Kushal Jun 21 '12 at 18:45
  • Thanks a lot!! but re-positioning in `onAnimationEnd()` causes imageview to flicker once. :-/ – Kushal Jun 21 '12 at 20:22
  • 1
    Before setting the LayoutParms you have to clear the animation (see above) – D-32 Jun 21 '12 at 20:27
  • I think you should use `LinearLayout.LayoutParams` instead only `LayoutParams` otherwise `setMargins()` not available. – Pratik Butani May 14 '15 at 18:46
  • 1
    Just to add things up, you don't need to set margin manually after animation ends, if you set setFillAfter to true instead of false. animation.setFillAfter(false); – Abhishek Patidar Nov 30 '15 at 12:01
  • https://stackoverflow.com/a/70812265/4606860 – Sachin Singh Jan 22 '22 at 11:21
10

It is better to use ObjectAnimator which actually moves the ImageView to the new position.
E.g.:

ImageView splash;

@Override
public boolean onTouchEvent(MotionEvent event) {
    float tx = event.getX();
    float ty = event.getY();

    int action = event.getAction();
    switch(action) {
        case MotionEvent.ACTION_DOWN:
            tx = event.getX();
            ty = event.getY();

            // findViewById(R.id.character).setX(tx-45);
            // findViewById(R.id.character).setY(ty-134);

            ObjectAnimator animX = ObjectAnimator.ofFloat(splash, "x", tx-45);
            ObjectAnimator animY = ObjectAnimator.ofFloat(splash, "y", ty-134);
            AnimatorSet animSetXY = new AnimatorSet();
            animSetXY.playTogether(animX, animY);
            animSetXY.start();

            break;
        default:
    }
    return true;
}
Ola Ström
  • 4,136
  • 5
  • 22
  • 41
abbasalim
  • 3,118
  • 2
  • 23
  • 45
6

you can use this code

imageView.animate().x(80).y(212).setDuration(300);

or

for soft animation you can use this library

https://github.com/wirecube/android_additive_animations

Diako Hasani
  • 1,384
  • 13
  • 14
2

In below code I am adding a image view in center on frame layout dynamically. After add I am increase scaling and set alpha to give zoom effect and after complete animation I am just translate my image view one position to another position.

Add image view on framelayout

    imgHeart = new ImageView(getBaseContext());
    imgHeart.setId(R.id.heartImage);
    imgHeart.setImageResource(R.drawable.material_heart_fill_icon);
    imgHeart.setLayoutParams(new FrameLayout.LayoutParams(50, 50, Gravity.CENTER));
    mainFrameLaout.addView(imgHeart);

Add animation on image view

       imgHeart.animate()
            .scaleXBy(6)
            .scaleYBy(6)
            .setDuration(700)
            .alpha(2)
            .setListener(new Animator.AnimatorListener() {
                @Override
                public void onAnimationStart(Animator animation) {

                }

                @Override
                public void onAnimationEnd(Animator animation) {
                    imgHeart.animate()
                            .scaleXBy(-6f).scaleYBy(-6f)
                            .alpha(.1f)
                            .translationX((heigthAndWidth[0] / 2) - minusWidth)
                            .translationY(-((heigthAndWidth[1] / 2) - minusHeight))
                            .setDuration(1000)
                            .setListener(new Animator.AnimatorListener() {
                                @Override
                                public void onAnimationStart(Animator animation) {
                                }

                                @Override
                                public void onAnimationEnd(Animator animation) {
                                // remove image view from framlayout
                                }
                                @Override
                                public void onAnimationCancel(Animator animation) {
                                }

                                @Override
                                public void onAnimationRepeat(Animator animation) {
                                }
                            }).start();
                }

                @Override
                public void onAnimationCancel(Animator animation) {

                }

                @Override
                public void onAnimationRepeat(Animator animation) {

                }
            }).start();
duggu
  • 37,851
  • 12
  • 116
  • 113
0

you can use this code :)

 private void animeView(View imageView){

        Handler handler = new Handler();
        final int[] deltaX = {50};
        final int[] deltaRotation = {45};
        handler.postDelayed(new Runnable() {
             @Override
             public void run() {
                 imageView.animate().translationX(deltaX[0])
                                    .rotation(deltaRotation[0]).setDuration(1000) ;
                 deltaX[0] *=-1 ;
                 deltaRotation[0] *=-1 ;
                 handler.postDelayed(this , 1000);
             }
         },1000);

    }
  • While this code may answer the question, it would be better to include some context, explaining how it works and when to use it. Code-only answers are not useful in the long run. – Abhishek Dutt Feb 25 '22 at 05:14