我正在创建一个游戏,我希望在给予他积分时向玩家展示一个简单的“得分” - 动画。这是我投射到屏幕上的视图:
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();
}
};
}
只要在任何给定时间屏幕上只有一个得分动画,此代码实际上效果很好。如果玩家再次得分,则在删除最后一个分数之前,应用程序崩溃 - 可能是因为第二个分数在动画期间获得了自动删除的事件。这是使用动画的不良做法吗?你们会怎么处理这个?
答案 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
解决了我的问题