Android: Reset animation position after completion

I use the animation defined in xml to shift the view from the screen. The problem is that as soon as the animation finishes, it returns to its original position. I need to know how to fix this. Here is the xml:

<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> <translate android:fromXDelta="0" android:toXDelta="-100%p" android:duration="500"/></set> 

Here is the Java that I use to call it:

  homeScrn = (View)findViewById(R.id.homescreen); slideLeftOut = AnimationUtils.loadAnimation(this, R.anim.slide_left_out); //Set Click Listeners For Menu btnHelp.setOnClickListener(new OnClickListener() { public void onClick(View v) { LayoutInflater.from(getApplicationContext()).inflate(R.layout.help, (ViewGroup)findViewById(R.id.subpage), true); homeScrn.startAnimation(slideLeftOut); } }); 

So basically, I am inflating the performance underneath. Then I animate the top view to the left. As soon as he leaves the screen and the animation is completed, he returns.

+58
android
Oct 07 2018-10-14
source share
8 answers

Animation works as expected. Just because you animated something doesn’t mean you really moved it. Animation affects only the drawn pixels during the animation itself, and not the widget configuration.

You need to add an AnimationListener and in the onAnimationEnd() method do something that makes your hyphenation permanent (for example, removes the top view from its parent element, marks the top view as having GONE visibility).

+79
Oct 07 2018-10-10
source share

Finally, a way to work has appeared, the right way to do this is: setFillAfter(true) ,

if you want to define your animation in xml you should do something like this

 <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator" android:fillAfter="true"> <translate android:fromXDelta="0%" android:toXDelta="-100%" android:duration="1000"/> </set> 

you can see that I defined filterAfter="true" in the set tag, if you try to define it in the translate tag, it will not work, there may be an error within!

and then in code

 Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide_out); someView.startAnimation(anim); 

OR

 TranslateAnimation animation = new TranslateAnimation(-90, 150, 0, 0); animation.setFillAfter(true); animation.setDuration(1800); someView.startAnimation(animation); 

then it will certainly work!

Now this is a bit complicated, as the view does move to a new position, but in fact the pixels in the view move, i.e. your view is actually in the starting position, but it doesn’t appear, you can check it if you see some kind of button or clickable view in your view (in my case in the layout) to fix what you need to manually move your view / layout to a new position.

 public TranslateAnimation (float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) new TranslateAnimation(-90, 150, 0, 0); 

now, as we see, our animation will start from -90 on the x axis to 150 on the x axis

what we do is set

 someView.setAnimationListener(this); 

and in

 public void onAnimationEnd(Animation animation) { someView.layout(150, 0, someView.getWidth() + 150, someView.getHeight()); } 

now let me explain public void layout (int left, int top, int right, int botton)

it moves your layout to a new position, the first argument defines the left one, we are 150 because the translation animation animated our view 150 x-axis , top is 0 because we did not animate the y axis, now we have done someView.getWidth() + 150 in the right someView.getWidth() + 150 , basically, we got the width of our view and added 150 , because on the left we now go to 150 x-axis to make the viewing width the original, and the bottom one is equal to the height of our view.

I hope you understand the concept of translation, and still you have questions that you can ask immediately in the comments section, I will be happy to help :)

EDIT Do not use the layout() method, as it can be called by the infrastructure, when the view is ever invalid and your changes will not be LayoutParams , use LayoutParams to set the layout parameters according to your requirement

+103
Apr 04 '13 at 10:29
source share

I may be a little late with the answer, but I have a solution for this:

Just add android:fillAfter="true" to your xml

+23
Jul 26 '11 at 9:12
source share

you can use

 fillAfter=true fillEnabled=true 

your view will not be reset to its original position, but if you have any buttons or anything else in your view, their position will not change.

You must use ObjectAnimator , it works from API level 11. It changes the position of the view automatically,

here is an example

 ObjectAnimator objectAnimator= ObjectAnimator.ofFloat(mContent_container, "translationX", startX, endX); objectAnimator.setDuration(1000); objectAnimator.start(); 

Thanks JUL for his answer

If your application is not found object animator , change the API level from Project -> properties -> Android than import android.animation.ObjectAnimator;

Regards Ike

+9
Dec 05 '12 at 16:10
source share

You need to add this command:

 final Animation animSlideLeft = new TranslateAnimation(0, -80, 0,-350, 0, 0, 0, 0); animSlideLeft.setFillAfter(true); 
+7
Mar 27 '16 at 15:08
source share

I went to the same question and solved it with setting marginLeft to OnAnimationEnd () ..

MarginLayoutParams params = (MarginLayoutParams) this.getLayoutParams(); params.setMargins(this.getWidth()*position, 0,0,0); this.setLayoutParams(params);

+1
Jun 01 2018-12-12T00:
source share

This problem has been bothering you for more than a week. And Muhammad answered me to the forefront to solve it.

I used markup to implement sidebars with animations. "view.layout will not be permanent. You must use LayoutParams, which will be permanent."

Here's my solution: (Use which type of LayoutParameter depends on your own parent layout):

 @Override public void onAnimationEnd(Animation animation) { FrameLayout.LayoutParams layoutParams=new FrameLayout.LayoutParams(screenWidth, screenHeight); layoutParams.setMargins((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight); for(View v:views) { v.setLayoutParams(layoutParams); //v.layout((int) -(screenWidth * RATE), 0, (int) (screenWidth - screenWidth * RATE), screenHeight); v.clearAnimation(); } } 
+1
Jul 17 '13 at 21:17
source share

Use the helper methods below to easily revitalize your look. Then you can animate and reset after completion, like this:

 // Animate the view: fly( view1, (float) 0, (float) 0, (float) 0, (float) 1000, 250, null, null, () -> { // Return the view to initial position on animation end: fly( view1, (float) 0, (float) 0, (float) 0, (float) 0, 0); return null; }); 

Helper Methods:

 /** * Translation of a view. */ public static void fly( View view, float fromXDelta, float toXDelta, float fromYDelta, float toYDelta, int duration) { fly( view, fromXDelta, toXDelta, fromYDelta, toYDelta, duration, null, null, null); } /** * Translation of a view with handlers. * * @param view A view to animate. * @param fromXDelta Amount to shift by X axis for start position. * @param toXDelta Amount to shift by X axis for end position. * @param fromYDelta Amount to shift by Y axis for start position. * @param toYDelta Amount to shift by Y axis for end position. * @param duration Animation duration. * @param start On animation start. Otherwise NULL. * @param repeat On animation repeat. Otherwise NULL. * @param end On animation end. Otherwise NULL. */ public static void fly( View view, float fromXDelta, float toXDelta, float fromYDelta, float toYDelta, int duration, Callable start, Callable repeat, Callable end) { Animation animation; animation = new TranslateAnimation( fromXDelta, toXDelta, fromYDelta, toYDelta); animation.setDuration( duration); animation.setInterpolator( new DecelerateInterpolator()); animation.setFillAfter(true); view.startAnimation( animation); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { if (start != null) { try { start.call(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onAnimationEnd(Animation animation) { if (end != null) { try { end.call(); } catch (Exception e) { e.printStackTrace(); } } } @Override public void onAnimationRepeat( Animation animation) { if (repeat != null) { try { repeat.call(); } catch (Exception e) { e.printStackTrace(); } } } }); } 
0
Jul 10 '18 at 7:34
source share



All Articles