ListView显示最后一条Item不完整问题分析

比如,有这么一个需求:实现一个IM类型的app聊天界面

要如何做呢?

很简单,一个title在顶部,一个输入框+按钮在底部 ,中间是一个ListView,搞定!!!

然后,ListView需要动态添加Item内容,并且,每添加一条Item都需要将ListView显示在最后一条。


好了,这次要解决的就是上面加粗部分的问题。


这时候有人要说了,调用setSelection()不就ok了嘛~ 

的确,正常情况下调用

mListView.setSelection(ListView.FOCUS_DOWN)

就可以实现上面的效果了。


既然有正常情况,自然就会有特殊情况咯!

没错,博主就遇到了特殊情况:

ListView添加的Item内部包含有图片,只显示图片的一部分,另一部分需要手动滑出来...


下面是分析过程:

首先,我注意到我的图片Item由于图片的尺寸不确定,所以ImageView的宽高是wrapcontent。

莫非是因为ListView在计算Item高度的时候,计算错误了?我一度是这么认为的。。。

直到跟着这篇 Android ListView工作原理完全解析,带你从源码的角度彻底理解 博客撸了一遍ListView的源码,

发现ListView建立会有三次Layout,但是在第一次Layout结束就调用了Adapter的getView函数,

并且对加载的Item进行了测量。这么说来,ListView测量Item的高度不可能出错啊。。。


那问题到底在哪呢?


然后,我打印了一些ListView加载过程的Log,发现本来一页只够3条Item加载的,可是

listView却加载了4条,导致最后一条无法显示完整。所以还是Item高度搞错了嘛!!!


接下来,我耗费了一整天的时间,查阅各种网站,无果。百思不得其解:明明listview测量

了item,为何item的高度还是出错?这世界还有没有信任可言?!!!


最后,我决定将项目中的东西抽出来,我用ListView重新做一遍看看到底怎么个回事。

然后,问题就顺利浮出水面了。在adapter的getView中调用了一个加载图片的函数,在函数

中是用AsyncTask从后台加载图片。。。 

所以在ListView第一次测量时,图片还没有加载到ImageView中去,那么Listview测量出的Item

的高度自然就是错的了。不过,Android肯定不会留这么大一个bug在系统中的,所以ListView

其实会多次测量Item的高度,不过由于setSelection()被调用的时候,ImageView中没有图片,

item的高度是错误的,而当测量出正确的高度时并没有再次调用setSelection(),所以就导致

了最后一个Item显示不全的bug。

那么解决的办法也就简单了,在adapter数据改变之后先调用一次setSelection(ListView.FOCUS_DOWN)

(这次调用是必须的,这次调用决定了系统加载哪一页的数据),然后用handler.postDelay延迟500ms

再调用一次setSelection()即可。


这里有一个复现bug的demo

 

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值