您的位置:首页 > 移动开发 > Android开发

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很多的情况下,封装之后的代码可以大大提高我们的编码效率,更主要的是内部高内聚,外部低耦合这一理念,体现的淋漓尽致!

水平有限,难免出错
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  listview adapter android