Android - 动画完成后移除视图

Android - remove View when its animation finished

嘿,我有一个方法可以将 TextView 添加到我的 FrameLayout 并启动动画。该方法应该能够更频繁地调用(对于多个动画)。这工作正常,因为我可以一次 运行 多个动画,但我想在动画完成后删除动画视图。

public void showMoneyAnimation(int amoutAddedOrRemoved){
    //Adding Money
        float textSize = Math.round((global.getDisplaySize().y / scaleValue) * 34.0);
        final TextView temp = new TextView(context);
        temp.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_END);
        temp.setText("+ " + amoutAddedOrRemoved + "$");
        temp.setTextAppearance(context, R.style.tsMoney1);
        temp.setTypeface(global.getFont("Grobold"));
        temp.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);

        sb_money.measure(0, 0);
        temp.measure(0,0);
        int xtemp = ((int) sb_money.getX() + sb_money.getMeasuredWidth()) - temp.getMeasuredWidth();
        temp.setX(xtemp);
        temp.setY(0);

        //Adding My Text to my FrameLayout
        bgFl.addView(temp);

        Animation atemp = AnimationUtils.loadAnimation(context, R.anim.addanim);
        temp.startAnimation(atemp);
        atemp.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                // This is the problem's origin!
                bgFl.removeView(temp);
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

但是我得到了 NullPointerException,可能是因为视图具有相同的名称? 我该如何解决这个问题?请帮助:)

这里是例外:

01-27 22:52:25.633  25975-25975/de.cookedapps.needforweed E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: de.cookedapps.needforweed, PID: 25975
java.lang.NullPointerException
        at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3146)
        at android.view.View.getDisplayList(View.java:14283)
        at android.view.View.getDisplayList(View.java:14330)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
        at android.view.View.getDisplayList(View.java:14225)
        at android.view.View.getDisplayList(View.java:14330)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
        at android.view.View.getDisplayList(View.java:14225)
        at android.view.View.getDisplayList(View.java:14330)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
        at android.view.View.getDisplayList(View.java:14225)
        at android.view.View.getDisplayList(View.java:14330)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
        at android.view.View.getDisplayList(View.java:14225)
        at android.view.View.getDisplayList(View.java:14330)
        at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3284)
        at android.view.View.getDisplayList(View.java:14225)
        at android.view.View.getDisplayList(View.java:14330)
        at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1588)
        at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1467)
        at android.view.ViewRootImpl.draw(ViewRootImpl.java:2754)
        at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2620)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2188)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1249)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6585)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
        at android.view.Choreographer.doCallbacks(Choreographer.java:603)
        at android.view.Choreographer.doFrame(Choreographer.java:573)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at android.app.ActivityThread.main(ActivityThread.java:5586)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
        at dalvik.system.NativeStart.main(Native Method)

您可能会在以这种方式删除视图时遇到问题,因为您应该只尝试从 UI 线程中触摸您的任何视图(以避免其他线程试图更改您的 UI 元素,这只会导致问题)。为此,Android 提供了一个名为 runOnUiThread() 的方法,它将指示您的代码在正确的线程中执行操作。

像这样的事情应该能让你找到正确的方向。将其放入您的 onAnimationEnd 方法中。

//get the parentView...
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);
            }
        });
    }
}

试试这个:

  1. 确保 bgFl 不为空
  2. 您可以尝试:temp.setVisibility(View.GONE) 而不是删除

或者

  1. 使用处理程序在 UI 线程中安全地删除视图。

如果您通过这种方式删除 bgFl.removeView(temp);,该功能将无法继续,这就是您看到该错误的原因。如果你想消失一个视图,使用 View.GONE

Kotlin 中像这样:

animation.doOnEnd {
binding.mainLayout.visibility = View.GONE}