Android中适用于ListView、GridView等组件的通用Adapter

Android中适用于ListView、GridView等组件的通用Adapter

分类:Android应用开发

ListView子项的布局文件

listview_item_layout.xml :

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android=""android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal" ><ImageViewandroid:id="@+id/my_imageview"android:layout_width="64dp"android:layout_height="64dp"android:contentDescription="@string/app_name" /><TextViewandroid:id="@+id/my_textview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="20dp"android:textSize="18sp" /></LinearLayout>曾经我们要写下的Adapter代码

public class NormalAdapter extends BaseAdapter {Context mContext;LayoutInflater mInflater;List<ListViewItem> mDataList;/*** @param context* @param data*/public NormalAdapter(Context context, List<ListViewItem> data) {mContext = context;mInflater = LayoutInflater.from(context);mDataList = data;}@Overridepublic int getCount() {return mDataList.size();}@Overridepublic ListViewItem getItem(int position) {return mDataList.get(position);}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null;if (convertView == null) {convertView = mInflater.inflate(R.layout.listview_item_layout, null, false);viewHolder = new ViewHolder();viewHolder.mImageView = (ImageView) convertView.findViewById(R.id.my_imageview);viewHolder.mTextView = (TextView) convertView.findViewById(R.id.my_textview);convertView.setTag(viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag();}viewHolder.mImageView.setImageResource(getItem(position).mDrawableId);viewHolder.mTextView.setText(getItem(position).mText);return convertView;}/*** ViewHolder** @author mrsimple*/static class ViewHolder {ImageView mImageView;TextView mTextView;}}

然而写过多遍以后我们发现我们总是重复地在写这些getCount、getItem、getView方法以及ViewHolder,导致了很多重复工作,,而且及其无聊,于是我把这些重复工作抽象起来(以前也有在github上看到这样的通用Adapter实现),整理一下也便于自己使用,也是自己学习的一个过程。下面我们看看使用CommonAdapter后我们做与上面同样的工作需要怎么写。

使用CommonAdapter后要写的代码

CommonAdapter<ListViewItem> listAdapter = new CommonAdapter<ListViewItem>(getActivity(),R.layout.listview_item_layout, mockListViewItems()) {@Overrideprotected void fillItemData(CommonViewHolder viewHolder, ListViewItem item) {// 设置图片viewHolder.setImageForView(R.id.my_imageview, item.mDrawableId);// 设置textviewHolder.setTextForTextView(R.id.my_textview, item.mText);}}其中mockListViewImtes是准备了一些数据, 代码如下 :

/*** 模拟一些数据** @return*/private List<ListViewItem> mockListViewItems() {List<ListViewItem> dataItems = new ArrayList<ListViewItem>();dataItems.add(new ListViewItem(R.drawable.girl_96, "girl_96.png"));dataItems.add(new ListViewItem(R.drawable.fire_96, "fire_96.png"));dataItems.add(new ListViewItem(R.drawable.grimace_96, "grimace_96.png"));dataItems.add(new ListViewItem(R.drawable.laugh_96, "laugh_96.png"));return dataItems;}

可以看到,我们的代码量减少了很多,如果一个项目中有好几个ListView、GridView等组件,我们就不需要重复做那么多无聊的工作了。我们看看效果图 :

CommonAdapter实现

/** * *created by Mr.Simple, Aug 28, 201412:26:52 PM. *Copyright (c) 2014, hehonghui@umeng.com All Rights Reserved. * *##################################################### *## *#_oo0oo_#*#o8888888o# *#88" . "88# *#(| -_- |)# *#0\ = /0#*#___/`—‘\___# *#.’ \\||# ‘.# *#/ \\||| : |||# \# *#/ _||||| -:- |||||- \# *#| | \\\ – #/ | |# *#| \_| ”\—/” |_/ |# *#\ .-\__ ‘-‘ ___/-. /# *#___’. .’ /–.–\ `. .’___# *#."" ‘< `.___\_<|>_/___.’ >’ "".# *#| | : `- \`.;`\ _ /`;.`/ – ` : | |# *#\ \ `_. \_ __\ /__ _/ .-` / /# *#=====`-.____`.___ \_____/___.-`___.-‘===== # *#`=—=’# *#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # *## *#佛祖保佑永无BUG# *## *##################################################### */package com.uit.commons;import android.content.Context;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import java.util.List;/** * 这是一个通用、抽象的适配器类,覆写了BaseAdapter的getCount, getItem, getItemId, * getView方法,在getView方法中通过 * 通用的CommonViewHolder来对convertView的进行处理,并且缓存convertView中的其他View元素 * ,降低了ListView、GridView 等组件的Adapter和ViewHolder的代码量. * 用户只需要在fillItemData函数中将第position位置里的数据填充到listview或者gridview的第position的view中即可 * ,具体使用实例参考文档. * * @author mrsimple * @param <T> 数据源的类型 */public abstract class CommonAdapter<T> extends BaseAdapter {/*** Context*/Context mContext;/*** 要展示的数据列表*/List<T> mData;/*** 每一项的布局id,例如R.layout.my_listview_item.*/private int mItemLayoutId = -1;/*** @param context Context* @param itemLayoutResId*每一项(适用于listview、gridview等AbsListView子类)的布局资源id,例如R.layout.*my_listview_item.* @param dataSource 数据源*/public CommonAdapter(Context context, int itemLayoutResId, List<T> dataSource) {checkParams(context, itemLayoutResId, dataSource);mContext = context;mItemLayoutId = itemLayoutResId;mData = dataSource;}/*** 检查参数的有效性** @param context* @param itemLayoutResId* @param dataSource*/private void checkParams(Context context, int itemLayoutResId, List<T> dataSource) {if (context == null || itemLayoutResId < 0 || dataSource == null) {throw new RuntimeException("context == null || itemLayoutResId < 0 || dataSource == null, please check your params");}}/*** 返回数据的总数*/@Overridepublic int getCount() {return mData.size();}/*** 返回position位置的数据*/@Overridepublic T getItem(int position) {return mData.get(position);}/*** item id, 返回position*/@Overridepublic long getItemId(int position) {return position;}/*** 返回position位置的view, 即listview、gridview的第postion个view*/@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// 获取ViewHolderCommonViewHolder viewHolder = CommonViewHolder.getViewHolder(mContext, convertView,mItemLayoutId);// 填充数据fillItemData(viewHolder, getItem(position));// 返回convertviewreturn viewHolder.getConvertView();}/*** 用户必须覆写该方法来讲数据填充到视图中** @param viewHolder 通用的ViewHolder, 里面会装载listview,*gridview等组件的每一项的视图,并且缓存其子view* @param item 数据源的第position项数据*/protected abstract void fillItemData(CommonViewHolder viewHolder, T item);}见所未见,闻所未闻。

Android中适用于ListView、GridView等组件的通用Adapter

相关文章:

你感兴趣的文章:

标签云: