Android 7.0 viewgroup cast exception
Android 7.0 viewgroup 强制转换相关异常
android 7.0 ListView 添加FootView 动态设置 LayoutParams 导致强制转换异常,这里列一下异常和解决方法。 (这里的错误仅在7.0及以上出现,其他版本暂无发现该问题)
该部分代码是出现在ListView 动态添加FootView的时候。
用代码添加了一个View , LayoutParams 没有使用ListView父类AbsListView而是使用ViewGroup.LayoutParams 引起的。
具体的异常信息如下:
java.lang.ClassCastException: android.view.ViewGroup$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
at android.widget.ListView.removeUnusedFixedViews(ListView.java:1908)
at android.widget.ListView.layoutChildren(ListView.java:1769)
at android.widget.AbsListView.onLayout(AbsListView.java:2162)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1741)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1585)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1494)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:726)
at android.view.View.layout(View.java:17637)
at android.view.ViewGroup.layout(ViewGroup.java:5575)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2346)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2068)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1254)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6337)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:874)
at android.view.Choreographer.doCallbacks(Choreographer.java:686)
at android.view.Choreographer.doFrame(Choreographer.java:621)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:860)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
很简洁的异常信息,除了系统sdk 中的代码错误,并没有发现自己代码中的异常部分。
出现的机型:
而且是Android 7.0 的新机器才会出现的问题(华为P9, 小米 5c 等 安装Android7.0 系统及其相关7.0 定制rom)
解决办法 :
很无奈的办法
注意将ViewGroup.LayoutParams 改成 ListView 需要的 AbsListView.LayoutParams
看图:

问题已解决, 具体问什么Android7.0 才出现这样的问题。 详细的原因还没有深入研究,随后续上。
续:
看图:

个人估计是 7.0 AbsListView.LayoutParams 虽然继承了ViewGroup.LayoutParams , 但是AbsListView.LayoutParams 添加了ViewType 类型, 并且在上图中的1911行进行强制的转换操作。 并且有相关的注释: 我们尊重在需要添加的 FixedViewInfo中View的LayoutParams 参数。 否则我们将为你添加,没有进行类型强制转换检查的操作。
并且在1913行的generateDefaultLayoutParams()中添加了生成了AbsListView.LayoutParams
@Override
protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
return new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0);
}
在 1015行重新添加了 对viewType的赋值
p.viewType = mAdapter.getItemViewType(position);
github上相关 issue :
https://github.com/idunnololz/AnimatedExpandableListView/issues/3