Android 4.4系统版本使用ListView造成cannot be cast to android.widget.AbsListView$LayoutParams的问题

在过兼容测试的时候,有个需求向下兼容到4.4版本,结果遇到闪退问题:

java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams

查看异常栈的调用:

at android.widget.ListView.setupChild(ListView.java:1826)
        at android.widget.ListView.makeAndAddView(ListView.java:1793)
        at android.widget.ListView.fillDown(ListView.java:691)
        at android.widget.ListView.fillGap(ListView.java:655)

发现它出错的代码在ListView的setUpChild中,于是查看setUpChild的代码:

在这里插入图片描述

可以看到这里强转出错了,也就是ListView中的每个ItemView的LayoutParams都必须是AbsListView.LayoutParams,代码顺着调用链往上看,即mkaeAndAddView方法看看:

在这里插入图片描述

可以发现传入setupChild的view是通过obtainView得来的,于是查看obtainView的代码(该方法在ListView的父类:AbsListView中实现):

在方法中调用了setItemViewLayoutParams(child, position)方法:

在这里插入图片描述

可以看到不论在setAdapter中的itemView的LayoutParams是什么类型,最终都一定被转为AbsListView.LayoutParams类型。但是为什么4.4的版本会报强转失败呢?去看看4.4的ListView源码,在obtainView方法中找到这个:

在这里插入图片描述
(链接:http://androidxref.com/4.4.4_r1/xref/frameworks/base/core/java/android/widget/AbsListView.java)

可以看到LayoutParams转化的条件是mAdapterHasStableIds,这个mAdapterHasStableIds是由mAdapter的hasStableIds决定的:

在这里插入图片描述

在BaseAdapter中默认返回false,回到看看代码中创建itemView的逻辑:

mFooterView = LayoutInflater.from(this).inflate(R.layout.footer_layout, this, false)

出错的原因是这个this并不是LisView,而是其他的View!

所以如果在4.4想解决这个问题:
在创建itemView时,这样创建(其实正常情况下都是这样创建的):

convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);

这里传入的parent为ListView:

在这里插入图片描述
这样就不会有错了。

为什么第2个参数为ListView就不会有错了?

可以跟进inflate的源码中看看:

在这里插入图片描述
可以看到通过root的generateLayoutParams方法获取了LayoutParams,并将值赋予了view的LayoutParams,因为ListView没有覆写这个方法,因此看看ListView的父类(AbsListView)的generateLayoutParams方法:

在这里插入图片描述

可以看到这个LayoutParams正是AbsListView.LayoutParams,所以自然不会报强转异常了!

总结

由于现在市面上几乎已经没有4.4的手机了,而且大多数时候创建通过LayoutInflater创建view时,都是在BaseAdapter的getView中创建,传入的第二个参数也是parent(即ListView),所以这个错误的出现是非常难得的,这里只是给出现问题的人提供解决方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哒哒呵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值