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);
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也是類似的。我就不舉例了哦。
封裝的類就那點兒玩意兒,就不貼源碼了。