摘要:Android开发中,ListView列表是使用率最高的UI组件,传统开发模式中,ListView的代码编写比较繁琐,项目中充斥着大量的Adapter适配器,该文在分析ListView开发原理的基础上,设计并实现一个可以通用于各种ListView场景开发的Adapter适配器,使得无论多少ListView,只需一个Adapter适配器,从而解决项目开发中代码高冗余、高复杂、管理麻烦等实际问题。
关键词:Android;ListView;Adapter;适配器
移动开发方兴未艾,如火如荼,各种App使我们的生活和工作变得快捷方便,Android平台作为两大移动操作系统之一,占据了移动开发的大半壁江山。
在Android App的开发实践中,ListView列表是使用最为频繁的UI组件,也是最为重要的内容呈现方式,几乎所有的App中都使用了数量不等的各种列表。众所周知,Android开发采用经典的MVC模式,因为ListView的这种重要性和普适性,An⁃droid系统在设计上使用MVC对其进行了精心的设计,一个ListView由三部分组成:
数据源:显示在界面上的具体数据,由数组或数据库等提供,对应于MVC中的M(模型)
Adapter适配器:将数据绑定到显示组件,并提供对数据的操作,对应于MVC中的C(控制器)
ListView组件:显示数据,响应用户输入,对应于MVC中的V(视图)
三者的关系如下图:

图1
这种模式中,Adapter适配器作为数据和显示之间的桥梁,是最为关键的一部分,每当需要显示列表中的某一项时,都会调用Adapter的getView方法返回一个View。在具体的开发中,对于每一个列表页面,我们通常要编写4个文件:
1)Activity的布局文件
2)Activity的类文件
3)ListView中Item的布局文件
4)Adapter的类文件
当项目比较简单时,这种设计有利于视图层和业务层分离解耦,从而提高灵活性和复用性,但是当项目中列表页面比较多时,每一个列表都需要一个Adapter文件,很容易导致源文件数量比较多,同时大量的Adapter文件中包含了很多相似代码,从而使得代码管理的复杂度和冗余度增大,进而大大降低这种设计所带来的好处。如果可以设计实现一个通用的Adapter可以适配各种不同的列表,则可以将这种副作用降到最低,从而提高我们的代码质量。
考虑以下几种常见的列表页面:

图2
列表1的Item包含2行文字,列表2的Item包含一个图片和2行文字,其布局不同,Adapter的处理也不尽相同,为了适用各种不同的布局和数据,我们可以使用Java的泛型技术来实现,下面是Adapter的实现代码:


这段代码与我们平时所写的Adapter十分相似,主要有以下区别:
1)行2,该类声明为抽象类,并使用<T>泛型声明;
2)行5和行8,列表数据使用<T>泛型声明,与行2结合,则可适配各种列表数据类型;
3)行34的getView( )方法与平时有所区别,这里使用了自定义的ViewHolder类来返回每一行的视图,一方面可以优化显示效率,另一方面通过该类完成通用适配的主要内容;
4)行42,定义了一个convert( ) 抽象方法,我们在使用通用Adapter进行具体开发时,必须通过重载此方法来设置Item的数据。


其中重点的部分是:
1)行3,使用稀疏数组保存View,因为实际使用时各种列表的Item布局是不同的,为了达到通用的目的,我们需要一个容器来保存Item布局中的所有控件,并且可以通过控件Id找到对应控件,这个容器也可以使用Map,不过出于性能考虑,这里使用稀疏数组;
2)行18,使用setTag( )方法将convertView与ViewHolder对象进行绑定,当返回convertView时,使用getTag( )方法拿到布局中的控件,从而提高效率;
3)行33,getView( )方法是ViewHolder的重点方法,同样使用<T>泛型,与CommonAdapter的<T>泛型结合,从而适配各种不同的Item布局;
4)行49开始的setText( )和setImageDrawable( )方法:实践中,绝大多数情况下,列表Item的布局中所使用到的控件,不过就是文本、图片、按钮、单选/复选等几种,所以我们可以在View⁃Holder中将设置文本/图片/属性/事件处理等功能进行封装,限于篇幅,这里只封装了设置文本和图片,读者可根据需要自行添加其他功能。
有了CommonAdapter和ViewHolder这2个类,一个通用的Adapter适配器就可以完成了,无论项目中使用了多少列表,我们也无需几十个Adapter满天飞了;使用该通用Adapter来完成前例中“列表2”的具体代码如下:

我们只需要根据Item布局重载convert( )方法并设置数据,代码简洁明了,神清气爽!
通过以上的实践,我们利用泛型技术结合面向对象思想,设计实现了一个可用于各种列表的通用Adapter,并在实际项目中成功地应用,使用该技术,可大大减少代码冗余,提高代码复用性,增强代码质量,降低项目管理的难度,具有较强的实用性。