試想下,資料配接器只是提供不同的資料並匹配介面中的組件以呈現不同的資料內容.那麼就可以對介面組件與資料項目入手進行修改.通常在BaseAdapter.getView中會使用ViewHolder方式來緩衝介面中的組件,以便提高效能.那我們可以定義一個DataViewHolder類[java] public class DataViewHolder { HashMap<Integer,View> mapView = new HashMap<Integer,View>(); HashMap<String,Object> mapData = new HashMap<String,Object>(); public void setView(int key,View v){ this.mapView.put(key, v); } @SuppressWarnings("unchecked") public <T> T getView(int key){ return (T)this.mapView.get(key); } @SuppressWarnings("unchecked") public <T> T getView(Class<T> clazz, int key){ return (T)this.mapView.get(key); } public void setData(String key, Object value){ mapData.put(key, value); } @SuppressWarnings("unchecked") public <T> T getData(String key){ return (T)mapData.get(key); } @SuppressWarnings("unchecked") public <T> T getData(Class<T> clazz, String key){ return (T)mapData.get(key); } } 對介面組件入手時,我們需要一個方法來提供一組介面組件的ID號,便於在BaseAdapter.getView方法中擷取該組件執行個體.[java] public int[] getFindViewByIDs() { return new int[]{ R.id.ItemText, R.id.ItemImage }; } 在實現BaseAdapter.getView方法時,通常需要擷取布局資源,那麼我們提供一個方法[java] public View getLayout(int position, DataViewHolder vh) { return inflater.inflate(R.layout.gv_content, null); } 以便在BaseAdapter.getView方法中調用,我們來實現BaseAdapter.getView方法[java] public View getView(int position, View convertView, ViewGroup parent) { DataViewHolder vh; if(convertView == null){ vh = new DataViewHolder(); convertView = this.getLayout(position,vh); //擷取布局資源 if(convertView == null) return null; int[] idAry = this.getFindViewByIDs(); //擷取介面組件 if(idAry == null)idAry = new int[]{}; for(int id : idAry){ vh.setView(id, convertView.findViewById(id)); //資源id作為key,緩衝介面中的組件 } convertView.setTag(vh); } else vh = (DataViewHolder)convertView.getTag(); this.renderData(position, vh); //繼承類中的方法,完成資料到介面組件的賦值 return convertView; } 對資料項目入手時,我們只需要定義泛型參數來支援,先暫時定義為HashMap<String,String>, renderData方法如下[java] public void renderData(int position, DataViewHolder vh) { HashMap<String,String> map = (HashMap<String,String>)this.getItem(position); vh.getView(TextView.class, R.id.ItemText).setText(map.get("title")); ImageView imgView = vh.getView(R.id.ItemImage); imgView.setImageURI(...); } 讓我們來看一下完整的實現[java] public abstract class DataAdapter<TItem> extends BaseAdapter { protected LayoutInflater inflater=null; protected Context mContext; private List<TItem> lst; public DataAdapter(Context c, List<TItem> lst){ this.mContext = c; this.lst = lst; this.inflater=LayoutInflater.from(c); } @Override public int getCount() { return lst.size(); } public void insert(TItem data){ lst.add(0, data); this.notifyDataSetChanged(); } public void append(TItem data){ lst.add(data); this.notifyDataSetChanged(); } public void replace(TItem data){ int idx = this.lst.indexOf(data); this.replace(idx, data); } public void replace(int index, TItem data){ if(index<0)return; if(index> lst.size()-1)return; lst.set(index, data); this.notifyDataSetChanged(); } public List<TItem> getItems(){ return lst; } @Override public Object getItem(int position) { return lst.get(position); } public TItem getItemT(int position) { return lst.get(position); } @Override public long getItemId(int position) { return position; } public void removeItem(int position){ if(lst.size()<=0)return; if(position<0)return; if(position>lst.size()-1)return; lst.remove(position); this.notifyDataSetChanged(); } public void clear(){ lst.clear(); this.notifyDataSetChanged(); } public abstract int[] getFindViewByIDs(); public abstract View getLayout(int position, DataViewHolder vh); public final View getResourceView(int id){ return inflater.inflate(id, null); } @Override public View getView(int position, View convertView, ViewGroup parent) { DataViewHolder vh; if(convertView == null){ vh = new DataViewHolder(); convertView = this.getLayout(position,vh); if(convertView == null) return null; int[] idAry = this.getFindViewByIDs(); if(idAry == null)idAry = new int[]{}; for(int id : idAry){ vh.setView(id, convertView.findViewById(id)); } convertView.setTag(vh); } else vh = (DataViewHolder)convertView.getTag(); this.renderData(position, vh); return convertView; } public abstract void renderData(int position, DataViewHolder vh); } 實際使用,如何使用DataAdapter類呢?我們還是要繼承來實現.[java] public class T1Activity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_t1); HashMap<String,String> map1 = new HashMap<String,String>(); map1.put("title","xxx"); map1.put("url","xxx"); ... List<HashMap<String,String>> al = new ArrayList<HashMap<String,String>>(); al.add(map1); //添加資料 al.add(map2); //添加資料 ... PrgmAdapter adapter = new PrgmAdapter(T1Activity.this, al); //執行個體化資料配接器 GridView gridview=(GridView)findViewById(R.id.gridView1); gridview.setAdapter(adapter); } //實際使用要繼承來實現.現在我們不需要關心getView方法了(除非有特殊需求),只需要提供布局資源,組件資源號,並在renderData中完成賦值就OK了. private class PrgmAdapter extends DataAdapter<HashMap<String,String>>{ public PrgmAdapter(Context c, List<HashMap<String,String>> lst){ super(c,lst); } @Override public int[] getFindViewByIDs() { return new int[]{ R.id.ItemText, R.id.ItemImage }; } @Override public View getLayout(int position, DataViewHolder vh) { return this.getResourceView(R.layout.gv_content); } @Override public void renderData(int position, DataViewHolder vh) { HashMap<String,String> map = this.getItemT(position); vh.getView(TextView.class, R.id.ItemText).setText(map.get("title")); ImageView imgView = vh.getView(R.id.ItemImage); ... } } } 如果其他類型,例如String,則 [java] class StrAdapter extends DataAdapter<String>{} 完全可以再進行調整,比如設定資源ID提供一個方法,在getView中使用.目前就可以基本使用滿足通用性.