Android 萬能介面卡 簡化繁瑣的開發

soul_code發表於2016-01-10

專案中ListView GridView幾乎是必用的元件,Android也提供一套機制,為這些控制元件繫結資料,那就是Adapter。用起來雖然還不錯,但每次都需要去繼承一個BaseAdapter,然後實現裡面的一大堆方法,而我們每次最關心的無非就是getView方法,其餘的方法幾乎都是相同程式碼。這裡是不是就可以優化起來呢?在其次,我們在使用Adapter的時候,為了優化效能,常常會建立一個Holder。而Holder裡面每次存放的都是View,對Holer的操作無非也就是初始化,繫結資料,複用。這裡是不是也可以抽取抽取? 好了,廢話不多說,直接上程式碼。

首先第一步操作BaseAdapter公共部分抽取:

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);

}

第二步Holer的通用化

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;
	}
}

第三步使用

package com.css.volunteer.adapter;

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());
	}

}

到這裡 萬事大吉,以後每次寫Adaper的時候,無論你的Item佈局怎麼樣,只需要重寫一個方法繫結你的資料就OK,能節約不少開發時間。

相關文章