在一个项目里,如果ListView是经常用到的,我们可以选择对ListView进行封装,封装过后的ListView,在写Adapter的时候,可以省事很多.下面记录没有封装之前的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即可.
下面记录详细步骤.
public abstract class MyBaseAdapter extends BaseAdapter {
private ArrayList data;
public MyBaseAdapter(ArrayList 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 getHolder();
}
借助构造方法,在外加将数据集合传入内部,然后借助泛型可以很快的写出封装后的的getCount(),getItem(int position),getItemId(int position)三个方法.这里不做赘述.
下面详细解释getView方法的封装:
[getView方法的封装需要结合ViewHolder的封装一起]
public abstract class BaseHolder {
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;
}
}
结合一般的使用方法,现在使用封装的listView就简单了很多,先创建一个子类holder继承自BaseHolder,然后创建对应的子类adapter继承自MyBaseAdapter
将文章开始的一般写法改造之后如下:
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 data) {
super(data);
}
@Override
public BaseHolder getHolder() {
return new HomeHolder();
}
}
前后对比一下,是不是简化了很多呢!
如果项目中所用到ListView不多,那么没有必要对Adapter进行封装,太费劲.但是在ListView很多的情况下,封装之后的代码可以大大提高我们的编码效率,更主要的是内部高内聚,外部低耦合这一理念,体现的淋漓尽致!
水平有限,难免出错