Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove a View when animation ends?

Tags:

I'm creating a game and I would like to display a simple "score"-animation to the player when credits are given to him. This is the view I throw onto the screen:

public class Score extends FrameLayout {    public Score(Context context, int score) {     super(context);     TextView txt = new TextView(context);     txt.setText(String.valueOf(score).toUpperCase());       addView(txt);     Animation anim = AnimationUtils.loadAnimation(context, R.anim.score);     startAnimation(anim);     anim.setAnimationListener(animationListener);   }   private void Remove(){      ViewGroup parent = (ViewGroup)getParent();       parent.removeView(this);    }    private AnimationListener animationListener = new AnimationListener() {      @Override     public void onAnimationEnd(Animation animation) {        Remove();     }     }; } 

This code actually works pretty well as long as there is only ONE score animation on screen at any given time. If the player scores again, before the last score was removed, the app crashes - probably because the second score gets the event to remove itself during animation.. Is this a bad practice of using Animation? How would you guys handle this?

like image 943
Svenhelge Avatar asked Jun 11 '10 18:06

Svenhelge


People also ask

How do I turn off infinite animation on Android?

Use clearAnimation() to stop an animation.


2 Answers

I also found that when removing a view from its parent after applying an animation to this view (using onAnimationEnd) crashes with NPE on the dispatchDraw of the parent.

The only solution I found is to trigger the removal inside a post call. Normally all UI modification must be done on the UI thread, so I added a runOnUiThread call on the activity, but it could be useless (it works for me without that).

Animation animation = AnimationUtils.loadAnimation(parentView.getContext(), animationId); animation.setAnimationListener(new AnimationListener() {     public void onAnimationStart(Animation paramAnimation) { }     public void onAnimationRepeat(Animation paramAnimation) { }     public void onAnimationEnd(Animation paramAnimation) {          // without the post method, the main UI crashes if the view is removed          parentView.post(new Runnable() {             public void run() {                 // it works without the runOnUiThread, but all UI updates must                  // be done on the UI thread                 activity.runOnUiThread(new Runnable() {                     public void run() {                         parentView.removeView(view);                     }                 });             }         });     } });  view.setVisibility(visibility()); view.startAnimation(animation); 
like image 64
wInd Avatar answered Sep 25 '22 20:09

wInd


For Kotlin language and using View Binding, this my solution:

      animation.setAnimationListener(object : Animation.AnimationListener {             override fun onAnimationStart(p0: Animation?) {             }              override fun onAnimationEnd(p0: Animation?) {                 mViewBinding                     .parentViewContainer                     .post {                          //The code below will be run on UI thread.                          mViewBinding                             .parentViewContainer                             .removeView(view)                     }             }              override fun onAnimationRepeat(p0: Animation?) {             }         }) 
like image 27
Tri Dawn Avatar answered Sep 25 '22 20:09

Tri Dawn