ListView 是个常用的组件,常用于展示列表数据。使用的时候通常会搭配一个 BaseAdapter 来进行数据的绑定,写多了之后发现,这些 BaseAdapter 都有一些重复或类似的代码,为了让 BaseAdapter 更纯粹,只专注于业务逻辑,所以对 BaseAdapter 进行进一步的抽象。
对于 BaseAdapter,通常需要关注的是 getView() 方法,在这个方法里面进行数据跟 UI 的绑定,其他的方法如 getCount()、getItem()、getItemId() 等都是固定的写法,这些方法可以封装起来。getView() 一般使用一个 ViewHolder 来重复利用 UI 组件进行性能优化,不然的话 ListView 随着数据的增大性能会急速下降,会卡成幻灯片一样,所以 getView() 里面的步骤也是类似的,区别的地方在于绑定数据和 UI 响应的部分不一样,所以可以只把绑定数据和 UI 响应部分抽象出来。
整体框架
先把 getCount()、getItem()、getItemId() 这几个固定的方法封装起来,搭建一个整体的框架,getView() 先留空,下一步再处理。
1 | /** |
封装 GetView()
getView() 通常的写法如下:
1 | @Override |
需要把整个步骤封装起来,抽象出 UI 组件初始化和更新部分,修改之后如下:
1 |
|
getView() 方法的封装就完成了
封装 ViewHolder
ViewHolder 需要提供两个方法供 getView() 调用: initView()、updateView(),代码如下:
1 | /** |
举个栗子
使用的时候,只需要重写四个方法: createViewHolder()、getLayout()、initView()、updateView() 即可。
1 | public class AppsAdapter extends CommonAdapter<ResolveInfo> { |
有图有真相,栗子效果:
完整的代码
CommonAdapter.java
1 | package cn.snaillauncher.adapter; |
CommonViewHolder.java
1 | package cn.snaillauncher.adapter; |