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

看图: image

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

续:

看图:

image

个人估计是 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

Table of Contents