android 奇怪BUG之 onAnimationEnd 中删除移动到屏幕外的View报错
当前项目情况如下,两个全屏控件,A和B (父控件是RelativeLayout)
A中有控件,点击后生成B 切使用平移Animation 将两个控件同时像左移(A出 B入)
B中有按钮,点击后使用Animation 同时讲两控件向右移(B出 A入) ,Amination 完成后删除B控件
BUG 产生, 4.1 以下版本(不包括4.1)
代码片段如下
View Code
1 final ChannelPage_Tab showingTab = channelPage_Tabs.get(ShowIngTag);
2 ChannelPage_Tab prveTab = channelPage_Tabs.get(--ShowIngTag);
3
4 Animation animation = AnimationFactory.getTranslateType(AnimationFactory.TRANSLATE_IN_RIGHT);
5 animation.setDuration(500);
6 animation.setFillAfter(true);
7 animation.setFillEnabled(true);
8 prveTab.startAnimation(animation);
9 animation.setAnimationListener(new AnimationListener() {
10 @Override
11 public void onAnimationStart(Animation animation) {}
12 @Override
13 public void onAnimationRepeat(Animation animation) {}
14
15 @Override
16 public void onAnimationEnd(Animation animation) {
17 showingTab.removeTag();
18 channelPage_Tabs.remove(showingTab);
19 }
20 });
21
22 animation = AnimationFactory.getTranslateType(AnimationFactory.TRANSLATE_OUT_RIGHT);
23 animation.setDuration(500);
24 animation.setFillAfter(true);
25 animation.setFillEnabled(true);
26
2 ChannelPage_Tab prveTab = channelPage_Tabs.get(--ShowIngTag);
3
4 Animation animation = AnimationFactory.getTranslateType(AnimationFactory.TRANSLATE_IN_RIGHT);
5 animation.setDuration(500);
6 animation.setFillAfter(true);
7 animation.setFillEnabled(true);
8 prveTab.startAnimation(animation);
9 animation.setAnimationListener(new AnimationListener() {
10 @Override
11 public void onAnimationStart(Animation animation) {}
12 @Override
13 public void onAnimationRepeat(Animation animation) {}
14
15 @Override
16 public void onAnimationEnd(Animation animation) {
17 showingTab.removeTag();
18 channelPage_Tabs.remove(showingTab);
19 }
20 });
21
22 animation = AnimationFactory.getTranslateType(AnimationFactory.TRANSLATE_OUT_RIGHT);
23 animation.setDuration(500);
24 animation.setFillAfter(true);
25 animation.setFillEnabled(true);
26
其中showingTab 就是A控件
prveTab就是B控件
产生BUG 的Log 片段如下
11-28 03:00:02.372: E/AndroidRuntime(1370): FATAL EXCEPTION: main
11-28 03:00:02.372: E/AndroidRuntime(1370): java.lang.NullPointerException
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2488)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.View.draw(View.java:10981)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.View.draw(View.java:10981)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.widget.FrameLayout.draw(FrameLayout.java:450)
11-28 03:00:02.372: E/AndroidRuntime(1370): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2126)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2026)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.os.Handler.dispatchMessage(Handler.java:99)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.os.Looper.loop(Looper.java:137)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.app.ActivityThread.main(ActivityThread.java:4424)
11-28 03:00:02.372: E/AndroidRuntime(1370): at java.lang.reflect.Method.invokeNative(Native Method)
11-28 03:00:02.372: E/AndroidRuntime(1370): at java.lang.reflect.Method.invoke(Method.java:511)
11-28 03:00:02.372: E/AndroidRuntime(1370): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-28 03:00:02.372: E/AndroidRuntime(1370): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-28 03:00:02.372: E/AndroidRuntime(1370): java.lang.NullPointerException
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2488)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.View.draw(View.java:10981)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2887)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.drawChild(ViewGroup.java:2885)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2489)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.View.draw(View.java:10981)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.widget.FrameLayout.draw(FrameLayout.java:450)
11-28 03:00:02.372: E/AndroidRuntime(1370): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2126)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2026)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.os.Handler.dispatchMessage(Handler.java:99)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.os.Looper.loop(Looper.java:137)
11-28 03:00:02.372: E/AndroidRuntime(1370): at android.app.ActivityThread.main(ActivityThread.java:4424)
11-28 03:00:02.372: E/AndroidRuntime(1370): at java.lang.reflect.Method.invokeNative(Native Method)
11-28 03:00:02.372: E/AndroidRuntime(1370): at java.lang.reflect.Method.invoke(Method.java:511)
11-28 03:00:02.372: E/AndroidRuntime(1370): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-28 03:00:02.372: E/AndroidRuntime(1370): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-28 03:00:02.372: E/AndroidRuntime(1370): at dalvik.system.NativeStart.main(Native Method)
从错误队列中找不到报错的原因,进过分析,大概问题就出现在animation End 以后的View 再次重绘步骤。
问题解决方式。
animation 的Listener 写在进入屏幕的那个控件上。BUG 不再出现。
其实最后还是不知道这个BUG 到底是因为什么产生的,大概产生的原因猜想就是因为animation 在end 以后,会再次调用父控件去重绘,此时这个时候拿到的子view 是null 导致的。

浙公网安备 33010602011771号