Android 中ListView的Adapter复用填坑记(一个ListView展示两种布局的坑)

“纸上得来终觉浅,绝知此事要躬行。”以前虽然经常听说Adapter有复用问题,但是没有自己遇到过之前,只是有个印象,但到底是什么问题?不知道!直到后来,一个ListView中需要展示两种布局,按照习惯哐哐哐写下去,结果后面一运行,咦~这都什么鬼?两种布局乱七八糟,本该是第一种布局在的地方,偶尔会冒出第二种布局,本该第二种布局在的地方,有时却是第一种布局。两种布局就像捣蛋的熊孩子,不听指挥。这时,才知道Adapter服用是什么问题。

一、ListView和Adapter的简单使用

Android应用中使用Adapter的地方很多,ListView的使用也很简单,使用ArrayAdapter、SimpleAdapter等内置Adapter就不多说,我们使用自由度最高的BaseAdapter,加载自己的布局。简单使用的代码如下:

1.在xml中定义ListView.

2.定义Adapter.

3.列表每项的视图布局

4.封装数据的model

5.最后在Activity或者Fragment中使用LIstView

这样,一个简单的ListView就完成,效果如下:

二、复用itemView,优化ListView

实际上ListView有复用机制,第一次只加载能铺满屏幕的itemView,当ListView上划或下拉,从屏幕上消失的itemVIew会进入Recycler,而即将显示的子项需要新的itemView时,会去Recycler中查找,如果已有则会服用。如下图:

再看我们Adapter,每次显示都会加载一次布局,但当item9显示在屏幕上的时候,实际上布局已经加载好了,我们在加载一次,造成了很大的资源浪费。因此,可以判断itemView(即convertView)是否已加载,如果已加载,则不必重新加载,只要设置改变属性就好。修改后的Adapter如下:

如图,用一个ViewHolder把View保存起来,下次使用itemView的时候,判断它是空的才会去加载布局,否则就从ViewHolder中吧View取出来,改变其属性,便可得到一个新的itemView!

三、复用Adapter遇到的坑

大部分Android应用的中ListView都是用以上方法实现的,而且一般情况下,列表的每一项都是一样的,这样已经够用了。但是,需求总是多种多样的,加入需要让listView的最后一项显示不同的布局,如下图。那我们该怎么办呢?

1.我们按步骤慢慢来,首先,在model中添加一个type字段,用来判断该使用哪种类型。如下图:

2.往dataList中添加一个model,并设置type为2。

3.添加最后一项的布局文件,注意,这一项没有ImageView,如下:

4.在Adapter中进行判断,将type为2的另一种布局加载进来。

OK,大功告成,在Adapter中进行了判断,如果type为2,就加载 illustration_list_item_2.xml,没毛病!我们run一下看看效果吧:

???歪?为什么前面会有ImageView?明明已经判断了啊!

分析:

还记得上一节讲的Adapter复用吗?加载最后一项的时候,回去Recycler中查找有没有多余的itemView,如果有则复用,convertView不为空,所以不会重新加载布局,只会设置属性。

既然这样,我们不做判空了,每次进入最后一项的时候都加载这个布局吧!反正只有最后一项使用了这个布局,不判空直接加载也不会造成多少浪费。Adapter代码修改如下:

拉到最后一项,看下效果:

Perfect!成功了,我果然是天才!

然后,往上拉一下……纳尼?闪退了?看下日志:

空指针?检查一下代码,原来是大意了,没有吧HoldView设置为convertView的Tag,把代码添加进去,重新运行:

OK,不闪退了!我果然是个天才……只要我不粗心。

上拉,下拉,看看效……等等,这是什么鬼?

为什么正常布局中.出了一个叛徒?

分析:

原来不光是最后一项会复用前面的布局,上拉的话前面的也会复用最后一项的布局。

这样改怎么办呢?怎么知道该再什么时候加载哪个布局呢?好吧,我承认有时候我也不那么天才。

既然不知道什么时候该加载什么布局,那我就把两种都放同一个布局里吧?代码如下:

这样的方法都让我想到了,我真是个人才!跟着我上拉、下拉一个慢动作,上拉、下拉慢动作重播……下面,见证奇迹的时刻到了!

 (╯°Д°)╯︵ ┻━┻悠悠苍天,何薄于我!

哐哐哐~

外卖小哥:你的外卖到了。

我:改bug呢,没时间吃外卖。

外卖小哥:我看看,你把一个布局显示的时候,忘了隐藏另一个布局了。

我:O_o 

经外卖小哥修改后,代码如下:

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值