`

ListView 编程: Adapter 何方神圣?

 
阅读更多

本来是想用一篇博客一口气写完:如何优化ListView ,但是我发现这样做吃力不讨好,一方面,自己太累,另一方面给人的感觉是在记账,根本不是在交流。


最后还是觉得分开写会好一点,每一篇突出一个重点比较好。欢迎交流。


在这篇博客中,你可以了解到:


1)Adapter(适配器)模式简介


2)android Adapter 类简介


3)android Adapter 与 ListView 之间的关系。


4)如何自定义 Adapter 以及注意事项


设计模式很抽象,熟练使用各种设计模式需要不断地实践和思考。Adapter,适配器,也是一种设计模式(适配器模式)。


关于适配器模式,在这里可以打个比方:android 手机需要充电,但是你不可以直接使用 220v 的电压来给它充电除非你恨透了这个设备。那么,我们会使用标准的充电器来给该手机充电(它会进行电压电流的转换),那么这个充电器就好比 Adapter(适配器)。


GOF 关于 Adapter 模式是这样解释的:

将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使原本由于接口不兼容而不能一起工作的那些类可以一起工作。


当然,这篇博客不是讲解 Adapter 模式的,关于该模式大家可以 GOOGLE 一下。


android 中 Adapter 是一个接口,api 声明如下:




该接口有很多间接或者直接的子接口、实现类。



ListView 在 APP 开发中使用比较频繁,而 Adapter 是 ListView 与数据打交道的桥梁,当列表里的每一项显示到页面时,都会调用Adapter的getView方法返回一个View

二者的关系可以使用下图简单描述:



使用 ListView 的同时,一般会使用如 ArrayAdapter、SimpleAdapter、SimpleAdapter 来为其添加显示数据。


ArrayAdapter、SimpleAdapter、SimpleAdapter这三个类直接或者间接的继承了 BaseAdapter(该类是一个抽象类)类。


BaseAdapter(该类是一个抽象类)类,api 声明如下:




其中,ListAdapter、SpinnerAdapter 是 Adapter 的子接口。


一般为了是 UI 更加的人性化更加的美观,设计人员会自己写一个类继承 BaseAdapter。

那么举一个实例来看看如何实现这个子类,以及需要实现的方法的回调时机。


Activity 代码


FileViewAdapter (自定义 Adapter)代码



运行效果如图示:




那么,重写的那四个方法(@Override),调用情况如下。

运行该 App 之后,打印信息如下:



getCount 方法返回需要显示的数据的个数,在 FileViewAdapter 代码中 getCount 方法返回数据为 10(这个数据可以根据实际情况修改)。

从打印信息来看,getView 方法被调用了 10 次,这也正好说明 getCount 方法返回数据是多少,getView 方法就会被调用多少次。


再做一个测试,首先退出该 APP,再次启动该 APP,打印信息如下:




这次可以看出 getItemId 方法没有被调用。那么,何时会再次调用这个方法呢?点击列表中的任意一条数据,这里点击第一条数据,看看打印信息:




可以看出,getItemId 方法被调用,并且可以看出 ListView 中数据是以 0 开始为索引值的,类似数组的索引。

那么,思考一个问题,何时调用 getItem 方法呢,在 android 的 BaseAdapter 源码中没有发现直接调用 getItem 方法的代码(看小结吧)。


更多关于 Adapter 的方法,可以参阅 SDK API 文档。


小结:


1. 四个方法的重写

FileViewAdapter 继承 BaseAdapter,重写以下四个方法:getCount、getItem、getItemId、getView。


2. 绘制 ListView

首先,系统在绘制 ListView 之前,将会先调用 getCount 方法来获取 Item 的个数。之后每绘制一个 Item 就会调用一次 getView 方法(getCount 方法返回几个数据,getView方法 就会被调用几次),getView 方法内就可以使用自定义好的 xml 来确定显示的效果并返回一个 View 对象作为一个 Item 显示出来。


3. getView、getCount 方法

在绘制L istView 过程中完成了适配器的主要转换功能,把数据和资源以开发者想要的效果显示出来。重复调用getView,使得 ListView 的使用更为简单和灵活。

getView、getCount 两个方法是自定 ListView 显示效果中最为重要的,同时只要重写好了就两个方法,ListView 就能完全按开发者的要求显示。


4.getItem、getItemId 方法

而 getItem 和 getItemId 方法将会在调用 ListView 的响应方法的时候被调用到。


在 ListView 的源码中可以看出,很多地方都调用了 getItemId 方法,但是没有直接看到调用 getItem 方法的。那么,我们还是往深层次看吧,从 ListView 源码追踪到 AdapterView 源码,可以看到:


可以看出这两个方法都是 public 的,当我们调用这两个方法时候,就会调用 getItem 或者 getItemId 方法。

为了保证 ListView 的各个方法有效,这两个方法也得重写。


附录 -- xml 文件


main.xml



custom_fileview.xml



在这篇博客中,可以看出 getView 方法反复的被调用,从而产生很多对象,当数据量很大的的时候上面的做法效率肯定高不了,那么,如何优化呢?且听下回分解!




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics