Listview和gridview是超级常用组件,于是乎,应该封装一下直接拿来用用而不是每次都写Adapter,这样多么的麻烦是不。虽然国内外大牛都有封装过,但是我总结了两个封装好的Adapter分享出来供使用。直接上代码和例子吧,就不啰嗦了。
第一种方式的CommonAdapter:
import java.util.List; import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; /** * 万能适配器 * * @author Mr.Himan * * @param <T> * 数据源的数据类型 */ public abstract class CommonAdapter<T> extends BaseAdapter { /** * 上下文 */ protected Context mContext; /** * 数据源 */ protected List<T> listDatas; /** * Item布局ID */ protected int layoutId; public CommonAdapter(Context context, List<T> listDatas, int layoutId) { this.mContext = context; this.listDatas = listDatas; this.layoutId = layoutId; } @Override public int getCount() { return listDatas == null ? 0 : listDatas.size(); } @Override /** * 获取当前点击的Item的数据时用 * 在onItemClick中 parent.getAdapter().getItem(),获取当前点击的Item的数据 */ public Object getItem(int position) { return listDatas.get(position); } @Override public long getItemId(int position) { return position; } @Override /** * 只关心这一个方法 */ public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = ViewHolder.getViewHolder(mContext, convertView, parent, layoutId, position); fillData(holder, position); return holder.getMConvertView(); } /** * * 抽象方法,用于子类实现,填充数据 * @param holder * @param position */ protected abstract void fillData(ViewHolder holder, int position); }和原来的自定义Adapter很相似,最多就是使用了泛型,结合ViewHolder和抽象方法,请看下面ViewHolder的封装。
import android.content.Context; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; /** * * @author Mr.Himan Holer的通用化处理 * */ public class ViewHolder { /** * View容器,用于存放Holer中的View * 照顾下小白 SparseArray 是Android推荐使用的一个优化容器,相当于一个Map<integer,View> */ private SparseArray<View> mViews; /** * Item布局View convertView */ private View mConvertView; public ViewHolder(Context context, ViewGroup parent, int layoutId) { mViews = new SparseArray<View>(); mConvertView = LayoutInflater.from(context).inflate(layoutId, null); mConvertView.setTag(this); } /** * 获取ViewHolder * * @param context * 上下文 * @param convertView * @param parent * @param layoutId * 布局layout Id * @param position * @return */ public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutId) { if (convertView == null) return new ViewHolder(context, parent, layoutId); return (ViewHolder) convertView.getTag(); } /** * 获取Holder中的ItemView * * @param viewId * @return */ @SuppressWarnings("unchecked") public <T extends View> T getView(int viewId) { View item = mViews.get(viewId); if (item == null) { item = mConvertView.findViewById(viewId); mViews.put(viewId, item); } return (T) item; } /** * 获取convertView * * @return */ public View getMConvertView() { return mConvertView; } }其中还使用了优化容器SparseArray,这个容器是最近大牛们使用的非常火的容器,效率高出Map非常之多,而且最重要的是非常节约内存。
下面是使用例子:
import java.util.List; import android.content.Context; import android.widget.TextView; import com.css.volunteer.bean.VolTeamItem; import com.css.volunteer.bitmap.BitmapHelper; import com.css.volunteer.manager.R; import com.css.volunteer.view.CustomImageView; public class VolTeamAdapter extends CommonAdapter<Bean> { public VolTeamAdapter(Context context, List<Bean> listDatas, int layoutId) { super(context, listDatas, layoutId); } @Override protected void fillData(ViewHolder holder, int position) { TextView actNum = holder.getView(R.id.team_item_active_num); TextView time = holder.getView(R.id.team_item_time); TextView title = holder.getView(R.id.team_item_title); CustomImageView icon = holder.getView(R.id.team_item_icon); Beanitem = listDatas.get(position); actNum.setText(String.valueOf(item.getActiveSum()) + "个"); time.setText(String.valueOf(item.getTimeSum()) + "h"); title.setText(item.getName()); BitmapHelper.getInstance(context).display(icon, item.getPhoto()); } }各种使用例子都有,只要实现这个方法,就可以直接使用,gridview的使用方式一致,使用起来那叫一个方便。
第二种适配器的CommonAdapter:
package com.sgucai.convertnumber.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import com.sgucai.convertnumber.viewholder.ViewHolder; import java.util.List; /** * Created by Administrator on 2015/11/4. */ public abstract class CommonAdapter<T> extends BaseAdapter { protected List<T> mDatas; protected LayoutInflater inflater; protected Context mContext; protected int layoutId; public CommonAdapter(Context context ,List<T> mDatas,int layoutId){ inflater = LayoutInflater.from(context); this.mContext = context; this.mDatas = mDatas; this.layoutId = layoutId; } @Override public int getCount() { int count = 0 ; if(mDatas!=null){ count = mDatas.size(); } return count; } @Override public Object getItem(int position) { return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder viewHolder = getViewHolder(position,convertView,parent); convertView((int) getItemId(position),viewHolder, (T) getItem(position)); return viewHolder.getConverView(); } public abstract void convertView(int position,ViewHolder viewHolder, T item); public ViewHolder getViewHolder(int position, View convertView, ViewGroup parent){ return ViewHolder.getViewHolder(mContext,convertView,parent, layoutId,position); } }这个适配器的Adapter的封装是不是和第一个有很多不同,但是核心部分封装几乎都是相似的。接下来看看ViewHolder。
import android.content.Context; import android.graphics.Bitmap; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; /** * Created by Administrator on 2015/11/4. * * 必须保证view的Id不一样 */ public class ViewHolder { //用于存储view的集合 private SparseArray<View> mViews; //填充布局的View private View mConvertView; private int position; public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) { this.mViews = new SparseArray<View>(); this.position = position; this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false); //设置tag mConvertView.setTag(this); } /** * 获取viewholder对象 */ public static ViewHolder getViewHolder(Context context, View convertView, ViewGroup parent, int layoutID, int position) { if(convertView == null){ return new ViewHolder(context,parent,layoutID,position); } return (ViewHolder) convertView.getTag(); } /** * 获取布局中的控件 */ public <T extends View> T getView(int viewId){ View view = mViews.get(viewId); if(view == null){ view = mConvertView.findViewById(viewId); mViews.put(viewId,view); } return (T) view; } public View getConverView(){ return mConvertView; } /** * text设置文本 */ public ViewHolder setText(int textViewId, String text){ TextView tv = getView(textViewId); tv.setText(text); return this; } /** * 为image设置本地drawable图片 */ public ViewHolder setImageResourse(int imageViewId,int drawable){ ImageView imageView = getView(imageViewId); imageView.setImageResource(drawable); return this; } /** * 为ImageView设置bitmap图片 */ public ViewHolder setImageBitmap(int imageViewId, Bitmap bitmap){ ImageView imageView = getView(imageViewId); imageView.setImageBitmap(bitmap); return this; } }第二个ViewHolder和第二个也有些区别是不是,区别是,又将setText和setImageBitmap的方法封装了一遍。这样一来,更疯狂,更方便。
使用例子:
public class ConvertAdapter extends CommonAdapter { private Context context; private List mDatas; private ImageView ive; public ConvertAdapter(Context context, List mDatas, int layoutId) { super(context, mDatas, layoutId); this.context = context; this.mDatas = mDatas; } @Override public void convertView(final int position, ViewHolder viewHolder, Object item) { //如果要获取控件id就使用这个方式,但如果不需要,那就不用,text类型也是这样获取 // ive = = viewHolder.getView(R.id.ive); //获取网络图片的方式 viewHolder.setImageBitmap(R.id.ive,bitmap/*这儿是bitmap类型的图片,要将url中的图片解析成bitmap类型,自己使用工具了*/); //获取文本的方式 viewHolder.setText(R.id.tv_listview_item_game, mDatas.get(position).getName()); //JavaBean集合 //获取本地图片的方式 viewHolder.setImageResourse(R.id.ive, R.mipmap.heart_icon //这儿是本地图片id); } }是不是很暴力,很疯狂,很简单,今后再也不用担心去写Adapter了,不过要是特别复杂的嘛,还是自己去写保险一点,以上两种方式的万能适配器直接复制可用,不用担心会出什么问题。因为我早就用在了项目中经久考验了,没问题。
对了,gridview也是类似的。我就不举例了哦。
封装的类就那点儿玩意儿,就不贴源码了。