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

时间:2010-06-11 18:13: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();
    }  
  };
}

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

3 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

对于 Kotlin 语言并使用视图绑定,这是我的解决方案:

      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?) {
            }
        })

答案 2 :(得分:0)

使用public abstract int intValue() Returns the value of the specified number as an int. This may involve rounding or truncation. Returns: the numeric value represented by this object after conversion to type int. AnimationUtils.loadAnimation解决了我的问题