How to remove a View when animation ends?
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 开发者_StackOverflow社区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?
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);
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?) {
}
})
When using AnimationUtils.loadAnimation
view.clearAnimation()
solved my problem
精彩评论