Android本身为ListView提供了几个方便的Adapter,比如ArrayAdapter、SimpleCurrentAdapter等等。但是为了实现更复杂的列表视图和控制,一般都要继承BaseAdapter来实现自己的Adapter。
我需要的ListView是如图一样的实现SD卡资源文件浏览列表,每个列表项由一个ImageView、TextView、CheckBox组成,并且要求当整个列表中有一个或一个以上的Checkbox被选中时,右上角的搜索按钮就显示出来,否则就隐藏,因此需要对每个列表项的CheckBox设置监听器。若使用Android提供的Adapter实现起来比较复杂,所以我选择继承BaseAdapter来实现自己的Adapter。
首先要知道的是ListView显示原理。ListView接收了Adapter之后,ListView的列表项数据是来源于接收的Adapter的。当ListView要展现出来的时候,ListView就会调用Adapter的getCount方法来获得一共需要绘制多少个列表项,之后就开始调用getView方法来获得每个列表项的View进行装载。也就是说ListView的列表项就是每次调用getView返回的View,每次调用getView获得的列表项View是什么样子,我们看到的这个列表项就是什么样子。
我继承BaseAdapter来实现自己的Adapter,至少需要重写基本的getView、getCount、getItem、getItemID四个方法。其中getCount和getView的功能如上所述,所以我要想实现对每个列表项多选框按钮的监听就需要在getView中返回View给ListView之前,对View中的多选框设置监听器。getView方法中带三个参数public View getView(int position,View convertView,ViewGroup parent),一般都是将convertView最为返回的View。
在这里,需要插播说明一下Android系统对ListView的实现小细节。Android构造ListView列表项的时候每次只会构造足够满足屏幕显示数量的列表项,一般都是10个左右。当ListView的列表项多于屏幕能够显示的列表项的时候,ListView就可以上下拉动,每次拉动显示后续列表项时就会再次调用getView方法来构造后续列表项的View。如果ListView是首次显示出来,那么getView的参数View convertView就是null空的;如果是拉动ListView调用的getView,那么这时getView的参数convertView就不再是null,而是随着拉动刚刚被拉走隐藏掉的列表项的View。这么做的好处是可以节省资源。
基于这个细节,如果重写getView方法时,要将参数convertView作为返回View,那么getView中就应该判断convertView是否为null。为空的话就需要使用Inflater构造出来,不为空的话就可以直接使用了。我的需求中需要对多选框进行监听,所以在返回convertView之前需要中convertView中获取多选框控件并设置监听器。
一开始,我以为这样就能够实现我的需求了,但是出来的结果却意想不到。当我点击一个多选框后,将列表往下拉,下面出来的没有选中的列表框也变成选中的状态。注意到我每次点击一个多选框后往下拉同步被选中的多选框的距离都是不变的,总是相隔11项。于是,回想getView中convertView参数的特点,当我往下拉的时候,ListView调用getView方法中的convertView就是回收来的因为拉动被隐藏的View。在我这个例子中,由于多选框是一种带有状态标示的控件,我的getView没有对其状态进行重新设置,所以就造成了这种奇怪现象。我的解决方法是在我实现的Adapter类中创建一个boolean数组用于保存对应列表项多选框的状态(getView中第一个参数position就是列表项ID,是根据数据来标识,不是根据列表项View来标识的,所以可以根据position来对列表项数据进行选中和非选中标识),每次调用getView都会在其中判断position位置上的boolean值来决定多选框的状态。
同样的,基于这个原理,使用其它带状态的控件也需要注意getView回收的问题。当然,也可以不使用convertView最为getView的返回结果,而在getView每次调用都重新构造一个View,或者Adapter类中构造一个与数据数量等长的View数组。不过这么做的话就比较消耗资源。
另外,BaseAdapter中的getItem和getItemId方法再构造ListView构造过程中并没有使用过,不过据说是在关于ListView的一些监听器中会调用到,所以继承BaseAdapter时最好也给这两个方法返回一个有意义的值。getItemId一般返回对应的position,getItem返回对应position的列表数据对象。
Adapter实现ListView带多选框等状态的自定义控件的注意事项
2021-01-05 11:56Android开发网 Android
Android本身为ListView提供了几个方便的Adapter,比如ArrayAdapter、SimpleCurrentAdapter等等,接下来介绍自定义Adapter实现ListView带多选框等状态控件的注意事项,感兴趣的朋友可以详细了解下,或许对你有所帮助
延伸 · 阅读
- 2022-03-02android 之listview 优化方法
- 2022-02-20Android TV开发:使用RecycleView实现横向的Listview并响
- 2022-01-24C#中WPF ListView绑定数据的实例详解
- 2022-01-24C# WPF ListView控件的实例详解
- 2022-01-17C#如何将Access中以时间段条件查询的数据添加到
- 2022-01-10ListView用法中与滚动相关的需求实现
- Android
Android的Service应用程序组件基本编写方法
Service是一个android 系统中的应用程序组件,它跟Activity的级别差不多,但是他没有图形化界面,不能自己运行,只能后台运行,Service通常用来处理一些耗时比...
- Android
android fm单体声和立体声的切换示例代码
android fm单体声和立体声的切换示例代码,切换是需要在一定的条件下满足才会进行切换,切换的条件和电台的信号强度RSSI、信号稳定性CQI等等都有关系...
- Android
Android 后台发送邮件示例 (收集应用异常信息+Demo代码)
今天介绍个更简单的方法,我们把异常信息收集后,通过后台发送邮件方法,把相关异常信息发送到我们指定的邮箱里面...
- Android
Android编程之在SD卡上进行文件读写操作实例详解
这篇文章主要介绍了Android编程之在SD卡上进行文件读写操作的方法,结合实例形式较为详细的分析了Android的文件操作及针对SD卡的存取操作相关技巧,需要的...
- Android
Android应用开发中实现apk皮肤文件换肤的思路分析
这篇文章主要介绍了Android应用开发中实现apk皮肤文件换肤的思路分析,包括布局和主要的皮肤更换逻辑实现,需要的朋友可以参考下...
- Android
Android基于API的Tabs3实现仿优酷tabhost效果实例
这篇文章主要介绍了Android基于API的Tabs3实现仿优酷tabhost效果,结合完整实例形式分析了Android实现优酷界面效果的相关技巧,需要的朋友可以参考下...
- Android
Android中查看USB连接的外接设备信息的代码实例
这篇文章主要介绍了Android中查看USB连接的外接设备信息的代码实例,需要的朋友可以参考下...
- Android
Android 捕获错误日志的方法
这篇文章主要介绍了Android 捕获错误日志的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...