Android translate animation - permanently move View to new position using AnimationListener

112,699

Solution 1

I usually prefer to work with deltas in translate animation, since it avoids a lot of confusion.

Try this out, see if it works for you:

TranslateAnimation anim = new TranslateAnimation(0, amountToMoveRight, 0, amountToMoveDown);
anim.setDuration(1000);

anim.setAnimationListener(new TranslateAnimation.AnimationListener() {

    @Override
    public void onAnimationStart(Animation animation) { }

    @Override
    public void onAnimationRepeat(Animation animation) { }

    @Override
    public void onAnimationEnd(Animation animation) 
    {
        FrameLayout.LayoutParams params = (FrameLayout.LayoutParams)view.getLayoutParams();
        params.topMargin += amountToMoveDown;
        params.leftMargin += amountToMoveRight;
        view.setLayoutParams(params);
    }
});

view.startAnimation(anim);

Make sure to make amountToMoveRight / amountToMoveDown final

Hope this helps :)

Solution 2

You should rather use ViewPropertyAnimator. This animates the view to its future position and you don't need to force any layout params on the view after the animation ends. And it's rather simple.

myView.animate().x(50f).y(100f);

myView.animate().translateX(pixelInScreen) 

Note: This pixel is not relative to the view. This pixel is the pixel position in the screen.

Solution 3

Just Do like this

view.animate()
            .translationY(-((root.height - (view.height)) / 2).toFloat())
            .setInterpolator(AccelerateInterpolator()).duration = 1500

Here, view is your View which is animating from its origin position. root is root View of your XML file.

Calculation inside translationY is made for moving your view to the top but keeping it inside the screen, otherwise, it will go partially outside of the screen if you keep its value 0.

Solution 4

You can try this way -

ObjectAnimator.ofFloat(view, "translationX", 100f).apply {
    duration = 2000
    start()
}

Note - view is your view where you want animation.

Solution 5

This is what worked for me perfectly:-

// slide the view from its current position to below itself
public void slideUp(final View view, final View llDomestic){

    ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationY",0f);
    animation.setDuration(100);
    llDomestic.setVisibility(View.GONE);
    animation.start();

}

// slide the view from below itself to the current position
public void slideDown(View view,View llDomestic){
    llDomestic.setVisibility(View.VISIBLE);
    ObjectAnimator animation = ObjectAnimator.ofFloat(view, "translationY",   0f);
    animation.setDuration(100);
    animation.start();
}

llDomestic : The view which you want to hide. view: The view which you want to move down or up.

Share:
112,699

Related videos on Youtube

mira
Author by

mira

Updated on July 09, 2022

Comments

  • mira
    mira almost 2 years

    I have android translate Animation. I have an ImageView with random generated position (next1, next2). I am calling void every 3 seconds. It generates new position of the View and then make animation and move View to destination position. Translate animation has AnimationListener implemented. When the animation finish, I move View permanently to the new position (in OnAnimationEnd). My problem is that animation position does not correspond with setting layoutParams positions. When animation end, it makes jump to a new position, which is about 50-100 pixels far. I think the positions should be the same because I use same values (next1, next2) in both situations. Please can you show me the way to find sollution ? Drawing of situation here here

     FrameLayout.LayoutParams pozice_motyl = (FrameLayout.LayoutParams)  pozadi_motyl.getLayoutParams();    
                TranslateAnimation anim = new TranslateAnimation(Animation.ABSOLUTE,pozice_motyl.leftMargin, Animation.ABSOLUTE, next1, Animation.ABSOLUTE, pozice_motyl.topMargin, Animation.ABSOLUTE, next2);
                anim.setDuration(1000);
                anim.setFillAfter(true);
                anim.setFillEnabled(true);
    
                anim.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {
                    }
    
                    @Override
                    public void onAnimationEnd(Animation animation) {
    
    
    
    
                        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(100, 100);
    
                        layoutParams.leftMargin = (int)(next1);
                        layoutParams.topMargin = (int)(next2);
                        pozadi_motyl.setLayoutParams(layoutParams);
    
                    }
    
                    @Override
                    public void onAnimationRepeat(Animation animation) {
    
                    }
                });
    
                pozadi_motyl.startAnimation(anim);
    

    Here is XML layout:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" 
        android:id="@+id/pozadi0"
        android:gravity="center_vertical"
        android:layout_gravity="center_vertical"          
        android:background="@drawable/pozadi2"
        >
    
    
    
    <LinearLayout
    android:id="@+id/pozadi_motyl"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            >
    
      <ImageView android:id="@+id/obrazek_motyl"
                 android:src="@drawable/motyl"
                 android:layout_width="100dip"
                 android:layout_height="100dip"
                             />
    
       </LinearLayout>
    
    
    <LinearLayout 
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
    <RelativeLayout
    android:id="@+id/obrazek_pozadi0"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
    
    
     <ImageView android:id="@+id/zaba_obrazek0"
    android:src="@drawable/zaba_obrazek"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerInParent="true"
    />
    
    </RelativeLayout>   
    </LinearLayout> 
    
    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    >
    
    <cz.zaba.Spojnice  
    android:layout_width="fill_parent"          
    android:layout_height="fill_parent" 
    />
    
    </LinearLayout>
    </FrameLayout>
    
  • Srikanth
    Srikanth over 10 years
    Thanks Gil. Minor correction: TranslateAnimation anim = new TranslateAnimation(0, amountToMoveRight, 0, amountToMoveDown);
  • Saro Taşciyan
    Saro Taşciyan about 10 years
    This causes a flicker, see: stackoverflow.com/questions/2650351/…
  • Valera
    Valera over 9 years
    no need to add listener, just use setFillAfter(true)
  • Gil Moshayof
    Gil Moshayof over 9 years
    @Valera doing this will cause unexpected behaviour when trying to intercept touch events on the animated view
  • Sufian
    Sufian almost 7 years
    For some reason I needed to put the body of onAnimationEnd() in a handler. I don't know why but a handler.post() worked, otherwise I'd see a little jerkiness at the end of animation.
  • the_prole
    the_prole about 4 years
    any way to set a listener?
  • the_prole
    the_prole about 4 years
    any way to set a listener?
  • Ankit Pandey
    Ankit Pandey about 2 years
    @the_prole mView.animate().translationY(pixelInScreen) .setListener(object : Animator.AnimatorListener { override fun onAnimationStart(animation: Animator?) {} override fun onAnimationEnd(animation: Animator?) { slideIn(binding.bottomTextContainer) } override fun onAnimationCancel(animation: Animator?) {} override fun onAnimationRepeat(animation: Animator?) {} })