android ArrayAdpater, BaseAdapter,SimpleAdapter,以及CursorAdapter

本文通過簡單分析android中的ArrayAdpater, BaseAdapter,SimpleAdapter,以及CursorAdapter,瞭解他們的不同,以及應用場合。以及繼承BaseAdapter實現更加靈活的Adapter
 android 開發文檔中關於Adapter的定義:An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View or each item in the data set
BaseAdapter是衆多adapter中極其重要的一個抽象類,實現了ListAdapter,SpinnerAdaper兩個接口,查看BaseAdapter源碼關於類的描述:
/**
 * Common base class of common implementation for an {@link Adapter} that can be
 * used in both {@link ListView} (by implementing the specialized
 * {@link ListAdapter} interface} and {@link Spinner} (by implementing the
 * specialized {@link SpinnerAdapter} interface.
 */
也就是說通過繼承BaseAdapter類自定義adapter,可以來自定義顯示ListView,SinnperAdapter等;在BaseAdapter類中存在DataSetObservable類的成員變量,用於當數據改變是通知給各個觀察者(view),關於DataSetObservable的設計應用了觀察者模式

ArrayAdapter<T>, CursorAdapter, SimpleAdapter等都是直接繼承與BaseAdapter:
ArrayAdapter<T>類:By default this class expects that the provided resource id references a single TextView。只用於顯示簡單的TextView,查看源碼中getView函數的實現即可明白
CursorAdapter: Adapter that exposes data from a {@link android.database.Cursor Cursor} to a {@link android.widget.ListView ListView} widget. The Cursor must include a column named "_id" or this class will not work.用於數據庫表內容顯示與ListView
SimpleAdapter:An easy adapter to map static data to views defined in an XML file. You can specify the data backing the list as an ArrayList of Maps. Each entry in the ArrayList corresponds to one row in the list. The Maps contain the data for each row. You also specify an XML file that defines the views used to display the row, and a mapping from keys in the Map to specific views.用於顯示一行中包含多個控件的ListView,如每行中包含一個ImageView和TextView


繼承BaseAdapter自定義Adapter:可以參考SimpleAdapter的源碼實現

/*
 * 繪製listView過程:先調用getCount獲取item個數,之後繪製一個item調用一次getView();
 * 可在getView()中使用預先定義的xml然後return出來顯示;
 * getItem和getItemId在調用listview相應方法時候調用
 */
public class PlanArrayAdapter extends BaseAdapter{
	protected ArrayList<Plan> planList;
	private Context context;
	private LayoutInflater inflater = null;
	private PlanDAO planDao = new PlanDAO();
	
	public PlanArrayAdapter(Context context) {
		this.context = context;
		inflater = LayoutInflater.from(context);
	}
	
	public int getCount() {
		// TODO Auto-generated method stub
		return planList.size();
	}

	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return planList.get(position);
	}

	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}
	
	//於每個View使用了一個ViewHolder來控制其內部的子item還使用了
	//setTag和getTag的方法 將holder綁定到了view上而不是直接的新建View 是對Adapter的優化。 
	//使用setTag和geTag,爲了避免內存消耗過大,重複使用holder的內存
	private static class ViewHolder {
		public TextView tvPlanContent;
		public TextView tvPlanDescription;
		}
	
//	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		Log.i("PlanArrayAdapter", "getView");
		final View view;
		if (convertView == null) {
			view = inflater.inflate(R.layout.adapteritem_plan, parent, false);
			ViewHolder holder = new ViewHolder();
			holder.tvPlanContent = (TextView) view.findViewById(R.id.textView_planContent);
			holder.tvPlanDescription = (TextView) view.findViewById(R.id.textView_planDescription);
			view.setTag(holder);
		} else {
			view = convertView;
		}
		
		ViewHolder holder = (ViewHolder) view.getTag();		
		final Plan plan = planList.get(position);
		holder.tvPlanContent.setText(plan.getPlanName().toString() );
		if(plan.getPlanDescription() != null)
			holder.tvPlanDescription.setText(plan.getPlanDescription().toString());
		return view;
	}
	
	public void updateData(ArrayList<Plan> plans) {
		planList = (ArrayList<Plan>)plans.clone();
		notifyDataSetChanged();
	}
}
另外具有setAdapter()函數的view類如spinner,GridView等,都可以考慮使用自定義Adapter來實現靈活多變的實現。


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