Search code examples
androidanimationtranslate-animation

Animate imageView from one side of screen to the other - android


I am trying to animate an ImageView using TranslateAnimation from it's current position (0,Yscreensize/2) to the other side of the screen (Xscreensize,imageview.getY()) but I can't manage it to work. here is my code:

    dart = (ImageView) findViewById(R.id.dart);
    Display disp = getWindowManager().getDefaultDisplay();
    Point poi = new Point();
    disp.getSize(poi);
    sizex = poi.x;
    sizey = poi.y;
    ViewTreeObserver vto = dart.getViewTreeObserver();
    vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        public boolean onPreDraw() {
            dart.getViewTreeObserver().removeOnPreDrawListener(this);
            finalHeight = dart.getMeasuredHeight();
            dart.setY(sizey / 2 - finalHeight);
            return true;
        }
    }); // till now - got screen size and set dart imageview to Y middle.

Now when I am trying to use the animation:

 TranslateAnimation animation = new TranslateAnimation(dart.getX(), sizex, dart.getY(), dart.getY());
 animation.setDuration(10000);
 dart.startAnimation(animation); // from current x to screen size, from currenty to currenty. 

this will not work and the dart just dissappear. what can I do?


Solution

  • Make the variable for the animation a class variable (to ensure it won't be garbage collected to soon). In order to make the ImageView stop its movement before it leaves the screen, you need an additional class variable

    float finalWidth;
    

    Then change your OnPreDrawListener like this:

    vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener()
    {
        public boolean onPreDraw()
        {
            dart.getViewTreeObserver().removeOnPreDrawListener(this);
            float finalHeight = dart.getMeasuredHeight();
    
            // if you want the view to stop before it leaves the screen
            float finalWidth = dart.getMeasuredWidth();
    
            animation = new TranslateAnimation(0, sizex - finalWidth, 0, 0);
            animation.setDuration(10000);
    
            // use this if you want the changes to persist
            // animation.setFillAfter(true);
    
            dart.setY(sizey / 2 - finalHeight);
            return true;
        }
    }); 
    

    I used a button to call 'startAnimation()'. The only problem when testing with an emulator is that the ImageView keeps running until it reaches the emulator window egde. So it disappears below the hardware controls region on the right side. In order to make it stop earlier, I tested with

        Rect myRect = new Rect();
        dart.getWindowVisibleDisplayFrame(myRect);
        sizex = myRect.width() * 0.9f;
        sizey = myRect.height();
    

    which almost did the trick. It's just an approximation, all right, but getting the exact dimensions of the display - taking into account paddings or insets - seems to be difficult. At least below API 20.

    Hope this helps anyway :)