android通用listview和gridview万能适配器实现的两种方式
2016-03-04 12:11
826 查看
Listview和gridview是超级常用组件,于是乎,应该封装一下直接拿来用用而不是每次都写Adapter,这样多么的麻烦是不。虽然国内外大牛都有封装过,但是我总结了两个封装好的Adapter分享出来供使用。直接上代码和例子吧,就不啰嗦了。
第一种方式的CommonAdapter:
下面是使用例子:
各种使用例子都有,只要实现这个方法,就可以直接使用,gridview的使用方式一致,使用起来那叫一个方便。
第二种适配器的CommonAdapter:
}
第二个ViewHolder和第二个也有些区别是不是,区别是,又将setText和setImageBitmap的方法封装了一遍。这样一来,更疯狂,更方便。
使用例子:
对了,gridview也是类似的。我就不举例了哦。
封装的类就那点儿玩意儿,就不贴源码了。
第一种方式的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); 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> { private List<Bean> item; //JavaBean类自己写咯 public VolTeamAdapter(Context context, List<Bean> listDatas, int layoutId) { super(context, listDatas, layoutId); this.item = listDatas; } @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; } <pre name="code" class="java">/** * 设置Text ForegroundColorSpan的值 * * @param viewId * @param ForegroundColorSpan */ public ViewHolder setText(int viewId, SpannableStringBuilder span) { TextView tv = getView(viewId); tv.setText(span); return this; } /** * 设置文本颜色 * * @param viewId * @param color * @return */ public ViewHolder setTextColor(int viewId, int color) { TextView tv = getView(viewId); tv.setTextColor(color); return this; } /** * 设置文本颜色,使用资源文件中的颜色 * * @param viewId 指定控件的id * @param resColorId 资源文件中color的id * @return */ @SuppressWarnings("deprecation") public ViewHolder setTextColorRes(int viewId, int resColorId) { TextView tv = getView(viewId); tv.setTextColor(mContext.getResources().getColor(resColorId)); return this; } /** * 给对象设置Tag * * @param viewId * @param key * @param tag * @return */ public ViewHolder setTag(int viewId, int key, Object tag) { View view = getView(viewId); view.setTag(key, tag); return this; } /** * 给View对象设置Tag * * @param viewId * @param tag * @return */ public ViewHolder setTag(int viewId, Object tag) { View view = getView(viewId); view.setTag(tag); return this; } /** * 给控件设置点击事件的监听器 * * @return */ public ViewHolder setOnClickListener(int viewId, OnClickListener listener) { View view = getView(viewId); view.setOnClickListener(listener); return this; } /** * 设置TextView的Drawable * * @param viewId * @param location * 图片位置 left top right down * @param ImageId */ @SuppressWarnings("deprecation") public ViewHolder setTextDrawable(int viewId, String location, int ImageId) { TextView tv = getView(viewId); if (location != null && location.length() != 0) { Drawable img = mContext.getResources().getDrawable(ImageId); img.setBounds(0, 0, img.getMinimumWidth(), img.getMinimumHeight()); if ("left".equals(location)) { tv.setCompoundDrawables(img, null, null, null); } else if ("top".equals(location)) { tv.setCompoundDrawables(null, img, null, null); } else if ("right".equals(location)) { tv.setCompoundDrawables(null, null, img, null); } else if ("down".equals(location)) { tv.setCompoundDrawables(null, null, null, img); } } else { tv.setCompoundDrawables(null, null, null, null); } return this; }
/** * 设置ImageView本地图片 * * @param viewId * @param ImageId */ @SuppressWarnings("deprecation") public ViewHolder setImageView(int viewId, int imageId) { ImageView iv = getView(viewId); iv.setImageDrawable(mContext.getResources().getDrawable(imageId)); return this; } /** * 设置九宫格 * * @param viewId * @param baseAdapter */ public ViewHolder setGridViewAdapter(int viewId, BaseAdapter baseAdapter) { GridView gv = getView(viewId); gv.setAdapter(baseAdapter); return this; } public ViewHolder updateGridViewLayoutParameters(int viewId, int colNum) { DefineGridView dgv = getView(viewId); GridViewUtil.updateGridViewLayoutParams(dgv, colNum); return this; } /** * 设置控件的Clickable * * @param viewId * @param clickable * @return */ public ViewHolder setClickable(int viewId, boolean clickable) { View view = getView(viewId); view.setClickable(clickable); return this; } /** * 设置控件的Enable * * @param viewId * @param isEnable * @return */ public ViewHolder setEnable(int viewId, boolean isEnable) { View view = getView(viewId); view.setEnabled(isEnable); return this; } /** * 设置控件的Pressed * * @param viewId * @param pressed * @return */ public ViewHolder setPressed(int viewId, boolean pressed) { View view = getView(viewId); view.setPressed(pressed); return this; } /** * 设置控件的Selected * @param viewId * @param selected * @return */ public ViewHolder setSelected(int viewId, boolean selected) { View view = getView(viewId); view.setSelected(selected); return this; } /** * 设置布局背景 * * @param viewId * @param resid */ public ViewHolder setBackground(int viewId, int resid) { View view = getView(viewId); view.setBackgroundResource(resid); return this; } /** * 设置控件是否隐藏 * */ public ViewHolder setVisibility(int viewId, boolean visible) { View view = getView(viewId); if (visible) { view.setVisibility(View.VISIBLE); } else { view.setVisibility(View.GONE); } return this; } /** * 设置控件是否隐藏 */ public ViewHolder setVisibility(int viewId, int visibility) { View view = getView(viewId); if (visibility == View.VISIBLE || visibility == View.INVISIBLE || visibility == View.GONE) { view.setVisibility(visibility); } 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也是类似的。我就不举例了哦。
封装的类就那点儿玩意儿,就不贴源码了。
相关文章推荐
- Android学习笔记----在一个应用程序中启动另一个应用程序
- Java/Android中线程池的应用
- Android中的IPC方式-Messenger
- Android如何通过手机自动获取短信验证码
- Android程序猿必看之《终端应用开发指南》
- Android自绘字体大小paint.settextsize随分辨率大小变化
- Android 版本更新
- Android实现自动填写获取验证码功能
- Android-FloatingActionButton
- Android-FloatingActionButton
- RES相关,Android支付相关记录
- android adb 连接手机出问题
- Android事件处理
- Android binder : 参考图
- Android Binder: Communication Mechanism of Android Processes
- Android Studio目录介绍
- Android EditText 校验手机号
- androidtag标签效果
- Android Studio集成极光推送(Jpush) 报错 java.lang.UnsatisfiedLinkError: cn.jpush.android.service.PushProtocol
- Android binder (2): Parcel