Android---封装ListView的Adapter
2016-07-21 10:40
363 查看
前言
在一个项目里,如果ListView是经常用到的,我们可以选择对ListView进行封装,封装过后的ListView,在写Adapter的时候,可以省事很多.下面记录没有封装之前的ListView写法,和封装之后的写法.没有封装之前的ListView
class HomeAdapter extends Base adapter{ @Override public int getCount() { return data.size(); } @Override public object getItem(int position) { return data.get(position); } @Override public int getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup viewGroup) { ViewHolder holder; if (convertView == null) { holder = new ViewHolder(); //1.加载布局文件 convertView = UIUtils.inflate(R.layout.list_item_home); //2.初始化控件 holder.tv_content = (TextView) convertView.findViewById(R.id.tv_content); //3.打标记 convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } //4.根据数据刷新页面 holder.tv_content.setText(getItem(position)); return convertView; } } class ViewHolder { TextView tv_content; }
从上面的一般写法中,我们可以看到,getCount(),getItem(int position),getItemId(int position)的重写一般都是固定模式的.唯一需要根据具体项目来实现的就是getView()方法,而getView方法里面可以总结为一下四个步骤:
加载布局文件
初始化控件
打标记
根据数据,刷新界面
根据上述步骤,可以将getView方法也进行封装
封装思路:
将BaseAdapter封装成MyBaseAdapter
将ViewHolder封装成BaseHolder
让BaseHolder和MyBaseAdapter打交道
在用到ListView的时候直接创建一个对应的Holder即可.
下面记录详细步骤.
对BaseAdapteer进行封装
public abstract class MyBaseAdapter<T> extends BaseAdapter { private ArrayList<T> data; public MyBaseAdapter(ArrayList<T> data) { this.data = data; } @Override public int getCount() { return data.size(); } @Override public T getItem(int position) { return data.get(position); } @Override public int getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup viewGroup) { BaseHolder holder; if (convertView == null) { //1.加载布局文件 //2,初始化控件fvb //3.打标记tag holder = getHolder(); }else{ holder= (BaseHolder) convertView.getTag(); } //4.设置数据刷新界面 holder.setData(getItem(position)); return holder.getRootView(); } /** *拿到holder的抽象方法,让子类实现 *@author zfy *@created at 2016/7/20 17:03 */ public abstract BaseHolder<T> getHolder(); }
借助构造方法,在外加将数据集合传入内部,然后借助泛型可以很快的写出封装后的的getCount(),getItem(int position),getItemId(int position)三个方法.这里不做赘述.
下面详细解释getView方法的封装:
[getView方法的封装需要结合ViewHolder的封装一起]
首先我们还是创建一个Holder,但是此处的Holder就是封装的BaseHolder;
然后还是判断convertView是否为空;
若为空,则在基类BaseHolder的getHolder()方法里完成前三个步骤;
若不为空,直接从tag里拿出;
步骤4是调用BaseHolder里的setData方法来实现的;
其中getHolder()是抽象方法,需要BaseHolder的子类来具体的实现;
setData()方法里也有抽象方法refreshView()也是让子类来具体实现;
对ViewHolder进行封装
public abstract class BaseHolder<T> { private View mRootView; private T data; //在构造方法中初始化布局 public BaseHolder() { //1.加载布局文件 //2.在initView方法中初始化控件 mRootView = initView(); //3.打标记 mRootView.setTag(this); } //基类不知道具体的实现,需要子类去具体的实现 public abstract View initView(); //让外界拿到跟item布局mRootView的方法 public View getRootView() { return mRootView; } //4.根据数据甩你界面的方法,由于基类不知道具体的实现,所以让子类完成 public abstract void refreshView(T data); public void setData(T data) { this.data = data; refreshView(data); } public T getData() { return data; } }
首先先一个抽象方法,initView(),这个方法暴露给子类,让子类在这个方法里面完成步骤1.2即:加载布局,初始化控件,这个方法返回的mRootView就是ListView的item的布局.然后将此方法写在BaseHolder的构造方法里面,只要一new BaseHolder或者其子类,该方法就会调用.
在构造方法里完成settag方法.
getRootView()方法用于外界的getView方法返回item的view
refreshView()抽象方法,是根据数据刷新界面的方法,也就是步骤4.
setData()方法内部调用的也是refreshView方法.
封装之后的用法
结合一般的使用方法,现在使用封装的listView就简单了很多,先创建一个子类holder继承自BaseHolder,然后创建对应的子类adapter继承自MyBaseAdapter将文章开始的一般写法改造之后如下:
创建一个HomeHolder
public class HomeHolder extends BaseHolder<String> { private TextView tv_content; @Override public View initView() { //1.加载布局 View view = UIUtils.inflate(R.layout.list_item_home); //2.初始化控件 tv_content = (TextView) view.findViewById(R.id.tv_content); //3.设置tag,在基类里面已经完成 return view; } //4.根据数据刷新界面 @Override public void refreshView(String data) { tv_content.setText(data); } }
2.重写HomeAdapter
class HomeAdapter extends MyBaseAdapter<String> { public HomeAdapter(ArrayList<String> data) { super(data); } @Override public BaseHolder<String> getHolder() { return new HomeHolder(); } }
前后对比一下,是不是简化了很多呢!
如果项目中所用到ListView不多,那么没有必要对Adapter进行封装,太费劲.但是在ListView很多的情况下,封装之后的代码可以大大提高我们的编码效率,更主要的是内部高内聚,外部低耦合这一理念,体现的淋漓尽致!
水平有限,难免出错
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories