在一个项目中,用到ListView的地方可能会很多,如果每一次都创建一次Adapter,再来一个ViewHolder就太伤感情了,特别是一个listView还带有加载更多的一个item,那么每一次都需要去实现。
所以对SuperBaseAdapter以及BaseHolder的抽取封装就十分有必要了:
对BaseHolder进行封装:
import android.view.View;
/**
* 作者:Created by Kevin on 2016/1/30.
* 邮箱:haowei0708@163.com
* 描述:ViewHolder的基类
*/
public abstract class BaseHolder<HODLERBEANTYPE> {
public View mHolderView;
private HODLERBEANTYPE mData;
public BaseHolder() {
//初始化根布局
mHolderView = initHolderView();
//绑定tag
mHolderView.setTag(this);
}
//初始化ViewHolder的视图
public abstract View initHolderView();
/**
* @des 设置数据刷新视图
* @call 需要设置数据和刷新数据的时候调用
*/
public void setDataAndRefreshHolderView(HODLERBEANTYPE data) {
// 保存数据
mData = data;
// 刷新显示
refreshHolderView(data);
}
/**
* @des 刷新holder视图
* @call setDataAndRefreshHolderView()方法被调用的时候就被调用了吧
*/
public abstract void refreshHolderView(HODLERBEANTYPE data);
}
再对BaseAdapter进行抽取:
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* 作者:Created by Kevin on 2016/1/30.
* 邮箱:haowei0708@163.com
* 描述:超级BaseAdapter
*/
public abstract class SuperBaseAdapter<BEANTYPE> extends BaseAdapter{
public List<BEANTYPE> mDataSource = new ArrayList<BEANTYPE>();
public static final int VIEWTYPE_LOADMORE = 0;
public static final int VIEWTYPE_NORMAL = 1;
public SuperBaseAdapter(AbsListView absListView, List<BEANTYPE> dataSource) {
super();
mDataSource = dataSource;
}
@Override
public int getCount() {
if (mDataSource != null){
return mDataSource.size();
}
return 0;
}
@Override
public Object getItem(int position) {
if (mDataSource != null){
return mDataSource.get(position);
}
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
BaseHolder holder = null;
if (convertView == null){
holder = getSpecialHolder();
}else {
holder = (BaseHolder) convertView.getTag();
}
//数据展示
holder.setDataAndRefreshHolderView(mDataSource.get(position));
return holder.mHolderView;
}
/**listView中可以显示的View类型*/
@Override
public int getItemViewType(int position) {
if (position == getCount() -1){//表示滑到底部:加载更多
return VIEWTYPE_LOADMORE;
}
return VIEWTYPE_NORMAL;
}
@Override
public int getViewTypeCount() {
return super.getViewTypeCount() + 1;
}
/**获取到各页面相应的Holder,由子类自己实现*/
public abstract BaseHolder getSpecialHolder();
}
然后构造相应的Holder继承baseHolder即可,这里是主页的Adapter:HomeAdapter
import android.view.View;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.example.administrator.googleplay.R;
import com.example.administrator.googleplay.base.BaseHolder;
import com.example.administrator.googleplay.bean.HomeBean;
import com.example.administrator.googleplay.global.Constants;
import com.example.administrator.googleplay.utils.BitmapHelper;
import com.example.administrator.googleplay.utils.StringUtils;
import com.example.administrator.googleplay.utils.UIUtils;
import com.lidroid.xutils.BitmapUtils;
import com.lidroid.xutils.ViewUtils;
import com.lidroid.xutils.view.annotation.ViewInject;
/**
* 作者:Created by Kevin on 2016/1/30.
* 邮箱:haowei0708@163.com
* 描述:主页的Holder
*/
public class HomeHolder extends BaseHolder<HomeBean.AppInfos>{
@ViewInject(R.id.item_appinfo_tv_title)
TextView tvTitle; //app标题
@ViewInject(R.id.item_appinfo_tv_size)
TextView tvSize; //app的大小
@ViewInject(R.id.item_appinfo_tv_des)
TextView tvDesc; //app的描述
@ViewInject(R.id.item_appinfo_rb_stars)
RatingBar rbStars; //星级
@ViewInject(R.id.item_appinfo_iv_icon)
ImageView ivAppIcon; //app的图标
@ViewInject(R.id.iv_download)
ImageView ivDownload; //下载的图标
@Override
public View initHolderView() {
View homeView = View.inflate(UIUtils.getContext(), R.layout.item_app_info, null);
//注入
ViewUtils.inject(this,homeView);
return homeView;
}
@Override
public void refreshHolderView(HomeBean.AppInfos data) {
tvTitle.setText(data.name);
tvSize.setText(StringUtils.formatFileSize(data.size));
tvDesc.setText(data.des);
rbStars.setRating(data.stars);
BitmapHelper.display(ivAppIcon, Constants.URLS.APPICON + data.iconUrl);
}
}
最后在listView的地方调用
HomeAdapter adapter = new HomeAdapter(listView,appInfoses);
listView.setAdapter(adapter);
private class HomeAdapter extends SuperBaseAdapter<HomeBean.AppInfos>{
public HomeAdapter(AbsListView absListView, List<HomeBean.AppInfos> dataSource) {
super(absListView,dataSource);
}
@Override
public BaseHolder<HomeBean.AppInfos> getSpecialHolder() {
return new HomeHolder();
}
}
这就是最基本的BaseAdapter的抽取,很多场景可以直接使用。当然如果有加载更多的功能的时候,需要使用更强力的BaseAdapter,下一篇来实现它。