RelativeLayout的坑

RelativeLayout的坑背景:因为某个功能,修改了listview的header的根布局,由原来的FrameLayout改为了RelativeLayout,目的是这样能更方便的去处理header里的各个元素之间位置。Bug出现场景:在Android4.2及以下的手机上加载列表的时候必崩,错误日志如下:刚开始没有关注BtsViewUtil的155行,因为这个是一个用了很久的工具类,主要就是对view进行mea

大家好,欢迎来到IT知识分享网。

背景:
因为某个功能,修改了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类型)

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/12585.html

(0)

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

关注微信