RelativeLayout的坑

背景:
因为某个功能,修改了listview的header的根布局,由原来的FrameLayout改为了RelativeLayout,目的是这样能更方便的去处理header里的各个元素之间位置。

Bug出现场景:
在Android4.2及以下的手机上加载列表的时候必崩,错误日志如下:
这里写图片描述
刚开始没有关注BtsViewUtil的155行,因为这个是一个用了很久的工具类,主要就是对view进行measure,应该没啥问题;而addHeaderView的第259行也是PinListView的自带方法,用了很久了,应该也没问题,然所以最后就把注意力放在了我自己写的代码BtsRouteOrderListFragment.addOriginHeaders里,主要代码就一句:

mPinListView.addHeaderView(mHeaderView);
看到是空指针异常,感觉应该比较容易解决,但是通过断点排查发现,这个地方地方不会存在为null的控件,可是日志确实显示是这个地方,而且是必现,这个null指针异常就显得很诡异了。
找不到原因,只能把修改的代码一点点回退,知道修改完header的布局文件,把RelativeLayout布局改回成FrameLayout后,代码成功运行了。。。
虽然一脸懵逼,不过因为是在低版本才会出现这个问题,心想可能是RelativeLayout的兼容性问题,查阅了一下官方文档,看到里面有个注释:
这里写图片描述
大致意思就是 在api17以前的版本,RelativeLayout有一个bug,就是在一个可以scrolling的容器中进行measure的话,如果自定义view没有使用UNSPECIFIED的话,就会默认使用AT_MOST来代替;确实是个坑,但是貌似和咱们这个空指针没太大关系。。。
无奈只能看源码,既然错误日志是在onMeasure里发生的,那就看看RelativeLayout的onMeasure方法。
api 18的代码:
这里写图片描述
因为刚开始进行初始化的时候,headerview只是被渲染出来,还没有attach到View层次树,所以这个mLayoutParam是null,这里就会报错;
而API 19的代码:
这里写图片描述
已经做了防护,所以新版本不会崩溃。
这也说明了为什么最开始的错误日志会显示在BtsViewUtil.java:155。

那FrameLayout应该有同样的问题啊,为什么不会崩溃?
看了下FrameLayout的代码,它里面压根没有用到mLayoutParam,所以不会崩溃。。

结论:1、在api 17之前,如果在scrollview或listview中使用ReletiveLayout,尽量不要手动调用measure。
2、在measure之前显式设置LayoutParams(代表着对父View的Layout请求,必须是父View的内部LayoutParams类型)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值