我们在使用ListView的时候,大多数时间都会继承BaseAdapter写适配器,会使用ViewHolder,然而当我们写的多了会发现,我们做了很多重复的体力劳动。接下来,为了提高开发效率、减少重复劳动,我对BaseAdapter进行了封装。(下面的结构参考于RecyclerView的Adapter方式实现)
1、BaseViewHolder
/**
* 用于ListView 的ViewHolder
* Created by HMY on 2016/3/2.
*/
public class BaseViewHolder {
public final View itemView;
public BaseViewHolder(View itemView) {
if (itemView == null) {
throw new IllegalArgumentException("itemView may not be null");
} else {
this.itemView = itemView;
}
}
}
2、BaseListAdapter
<pre name="code" class="java">/**
* Created by HMY on 2016/3/1.
*/
public abstract class BaseListAdapter<T, VH extends BaseViewHolder> extends BaseAdapter {
protected Context mContext;
protected List<T> mList;
protected ListView mListView;
protected LayoutInflater inflater;
public BaseListAdapter(Context context) {
this.mContext = context;
inflater = LayoutInflater.from(mContext);
}
@Override
public int getCount() {
return mList == null ? 0 : mList.size();
}
@Override
public Object getItem(int position) {
return mList == null ? null : mList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@SuppressWarnings("unchecked")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
VH holder = null;
if (convertView == null || convertView.getTag() == null) {
convertView = inflater.inflate(getLayoutResource(), parent, false);
holder = onCreateViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (VH) convertView.getTag();
}
onBindViewHolder(position, holder);
return convertView;
}
public abstract int getLayoutResource();
public abstract VH onCreateViewHolder(View convertView);
public abstract void onBindViewHolder(int position, VH holder);
public void setList(List<T> list) {
this.mList = list;
}
public List<T> getList() {
return mList;
}
public void setList(T[] list) {
ArrayList<T> arrayList = new ArrayList<T>(list.length);
for (T t : list) {
arrayList.add(t);
}
setList(arrayList);
}
public ListView getListView() {
return mListView;
}
public void setListView(ListView listView) {
mListView = listView;
}
public void add(T t) {
this.mList.add(t);
notifyDataSetChanged();
}
public void addAll(List<T> list) {
this.mList.addAll(list);
notifyDataSetChanged();
}
public void remove(int position) {
this.mList.remove(position);
notifyDataSetChanged();
}
public void clear() {
this.mList.clear();
notifyDataSetChanged();
}
}
由上可见,getCount、getItem、getItemId、getView这四个方法我们不在需要在重写,只需要实现getLayoutResource()、onCreateViewHolder(View convertView)、onBindViewHolder(int position, VH holder)这三个方法。
getLayoutResource() :返回item的布局资源id;onCreateViewHolder(View convertView):new一个ViewHolder对象;onBindViewHolder(int position, VH holder):绑定数据。
下面是我写的一个测试Demo:
1、BaseListTestAdapter
/**
* Created by HMY on 2016/3/1.
*/
public class BaseListTestAdapter extends BaseListAdapter<BastListAdapterTestModel, BaseListTestAdapter.ViewHolder> {
public BaseListTestAdapter(Context context) {
super(context);
}
@Override
public int getLayoutResource() {
return R.layout.item_adapter;
}
@Override
public ViewHolder onCreateViewHolder(View convertView) {
return new ViewHolder(convertView);
}
@Override
public void onBindViewHolder(int position, ViewHolder holder) {
BastListAdapterTestModel model = mList.get(position);
holder.iconIv.setImageResource(model.resid);
holder.textTv.setText(model.text);
}
public class ViewHolder extends BaseViewHolder {
ImageView iconIv;
TextView textTv;
public ViewHolder(View itemView) {
super(itemView);
iconIv = (ImageView) itemView.findViewById(R.id.iv_icon);
textTv = (TextView) itemView.findViewById(R.id.tv_text);
}
}
}
/**
* Created by HMY on 2016/3/1.
*/
public class BastListAdapterTestModel implements Serializable {
public int resid = 0;
public String text = "";
}
3、item_adapter.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:padding="5dp">
<ImageView
android:id="@+id/iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:clickable="false"
android:scaleType="fitCenter"
android:src="@drawable/abc_btn_check_to_on_mtrl_000"
android:visibility="visible"/>
<TextView
android:id="@+id/tv_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="7dip"
android:layout_toRightOf="@id/iv_icon"
android:text="text"
android:textColor="@android:color/black"
android:textSize="18sp"/>
</RelativeLayout>
</LinearLayout>
4、BaseAdapterActivity
public class BaseAdapterActivity extends Activity {
private Context mContext;
private ListView mListView;
private List<BastListAdapterTestModel> mDataList;
private BaseListTestAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_adapter);
initData();
initView();
}
private void initData() {
mContext = this;
getData();
mAdapter = new BaseListTestAdapter(mContext);
mAdapter.setList(mDataList);
}
private void initView() {
mListView = (ListView) findViewById(R.id.listView);
mListView.setAdapter(mAdapter);
}
private void getData() {
mDataList = new ArrayList<>();
BastListAdapterTestModel model = new BastListAdapterTestModel();
model.resid = android.R.drawable.alert_dark_frame;
model.text = "text1";
mDataList.add(model);
BastListAdapterTestModel model2 = new BastListAdapterTestModel();
model2.resid = android.R.drawable.alert_dark_frame;
model2.text = "text2";
mDataList.add(model2);
}
}
最后看一下效果图: