如何在动画结束时删除视图?

Sve*_*lge 22 android

我正在创建一个游戏,我希望在给予他积分时向玩家展示一个简单的"得分" - 动画.这是我扔到屏幕上的视图:

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();
    }  
  };
}
Run Code Online (Sandbox Code Playgroud)

只要在任何给定时间屏幕上只有一个得分动画,这段代码实际上效果很好.如果玩家再次得分,则在删除最后一个分数之前,应用程序崩溃 - 可能是因为第二个分数在动画期间获得了自动删除的事件.这是使用动画的不良做法吗?你们怎么处理这个?

小智 37

我还发现,在将动画应用到此视图后(使用onAnimationEnd)在父视图的dispatchDraw上与NPE崩溃时,从父项中删除视图时.

我发现的唯一解决方案是在后调用中触发删除.通常所有UI修改都必须在UI线程上完成,所以我在活动上添加了一个runOnUiThread调用,但它可能没用(没有它就适用于我).

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);
Run Code Online (Sandbox Code Playgroud)

  • `runOnUiThread`不是必需的.对视图执行发布将使ui线程中的runnable运行. (13认同)
  • 我认为它已经在ui线程上运行了.post()工作的一个可能原因(这只是一个猜测)是,如果您直接在动画侦听器方法中删除视图,它们将在绘制逻辑执行之前被调用,您将遇到NPE.例如,每个视图可以在绘制之前更新其动画状态,如果动画完成,则调用侦听器方法.当你发布一个runnable时,它将被looper排队,它可能不会处理任何消息,直到该帧的视图层次更新/绘制逻辑完成之后.可能都是ui线程 (5认同)