android的listview中getview()的问题

上周开始直到昨天,我和我的同事遇到了一个不大不小的bug。不多说先叙述一下:

产品需求:

是一个专辑页面,将优秀的,点击量高的文章做成一个专辑,方便大家阅读。就是一个listview,item有图的显示图,没图就不显示,但每个item都会有标题,有描述。有headerview,是这个专辑的标题和描述,也会有背景图,还有对专辑的收藏按钮和评论显示,点击收藏,按钮变色,点击评论,进入评论页面;有footerview,做一些其他专辑的推荐。相信经过我这样的描述,你的脑海中已经大致有了一个关于这样专辑的布局印象,这里我就不贴代码了。

出现问题:

为什么我对收藏和评论讲的很详细,因为问题就出现在了这里。

进入专辑页面后,当我点击收藏时,第一次是可以点击的并提示“已收藏”,当我再点击时,就不再响应点击事件了,注意,连点击事件都不响应了,就更别提以后的那些逻辑了。

点击评论按钮进入评论页面和它一样,也是点一次好使,第二次就不好使了。而且二者都是在不好使(不响应点击事件)之后,你点多少次都是白搭,都是不会响应,停在那里。但是只要你一滑动页面,无论滑动多么小的一点距离,刚才不响应的点击事件就会都响应出来,收藏仅仅是变色一次,而评论页面,你刚才点击多少次,它就会打开多少次。

分析问题:

把我们遇到的在网上一搜,发现类似问题还真不少,致使开始我们也以为是listview的item和button抢夺焦点问题,就xml上添加了几个属性,没有解决。

后来把点击事件加在listview的item上,发现响应,加在headerview上就是不相应,以为是布局的问题,因为我们的布局中有个incloud,我们就把incloud里面的内容提出来,没有解决。

又开始怀疑事件传递,将相关的都返回了fasle,发现还是不行。并在这一阶段发现每点击一次的时候,listview都要getview(),按理说,图片都已经down下来了,不应该,除非他重新计算位置。

深究getview()方法,在网上找到了这一篇,终于解决问题。很郁闷,弄了一溜八开的,竟然仅仅是个布局问题,而不是代码问题,更不是高大上的事件分法、线程同步的问题。记下了。现附上,博客地址http://www.cnblogs.com/manuosex/p/3426160.html

引用博客中的

这是什么样的情况了,看了网上的资料以后我知道原来没有设置器listview 的布局方式不是fill-parent,而是wrap-content,会计算父控件的高度所以造成了一种反复调用情况,从而次数不确定。
更深层次的解释为:

View在Draw的时候分成两个阶段:measure和layout,在measure阶段时主要就是为了计算两个参数:height和width。而且要注意的是,这是个递归的过程,从顶向下,DecorView开始依次调用自己子元素的measure。计算完成这两个参数后就开始layout,最后再是draw的调用。

对于ListView,当然每一个Item都会被调用measure方法,而在这个过程中getView和getCount会被调用,而且看用户的需求,可能会有很多次调用。

而为什么会有很多组次调用呢?

问题就在于在layout中的决定ListView或者它的父元素的height和width属性的定义了。fill_parent会好一点,计算方法会比较简单,只要跟父元素的大小相似就行,但是即使是fill_parent,也不能给View当饭吃,还是要计算出来具体的dip,所以measure还是会被调用,只是可能比wrap_content的少一点。至于自适应的它会一直考量它的宽和高,根据内容(也就是它的子Item)计算宽高。可能这个measure过程会反复执行,如果父元素也是wrap_content,这个过程会更加漫长。

所以,解决方法就是尽量避免自适应,除非是万不得已,固定大小或者填充的效果会比较好一些。

原文地址:https://www.cnblogs.com/devtrees/p/4423720.html