android通用listview和gridview萬能適配器實現的兩種方式

      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也是類似的。我就不舉例了哦。

封裝的類就那點兒玩意兒,就不貼源碼了。







  



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章