Android之Adapter的封裝與抽象
在開發的過程中,常常會用到ViewPager、ListView、GridView等、這些帶有Item的視圖控制項,而這些控制項有個共同點就是都要用到它們的適配器,我們在實現視圖展示時,一般都會去寫個自訂的適配器去繼承PagerAdapter或Adapter或Adapter的子類,因為Android源碼內建的這些適配器都比較抽象,往往在我們開發時,寫的一些自訂配接器都需要重寫Adapter父類的一些方法,在重寫時,有很多較通用性的代碼,比較耦合,下面將PagerAdapter和Adapter的子類BaseAdapter進行了封裝與抽象,免去了每次都去重寫這些通用的代碼,代碼如下:
1.ViewPagerAdapter
/** * 通用ViewPagerAdapter * @author Jenly * */public class ViewPagerAdapter extends PagerAdapter {private List listViews = null;public ViewPagerAdapter(List listViews) {this.listViews = listViews;}@Overridepublic void destroyItem(View container, int position, Object object) {((ViewPager)container).removeView(listViews.get(position));}@Overridepublic int getCount() {return listViews.size();}@Overridepublic Object instantiateItem(View container, int position) {((ViewPager)container).addView(listViews.get(position),0);return listViews.get(position);}@Overridepublic boolean isViewFromObject(View paramView, Object paramObject) {return paramView == paramObject;}public List getListViews() {return listViews;}public void setListViews(List listViews) {this.listViews = listViews;}}因為ViewPager的Item基本上都是繼承View,所以這個ViewPagerAdapter 基本上可作為ViewPager控制項的通用適配器。
2.AbstractAdapter
/** * 抽象適配器(免去一些有共性的代碼) * @author Jenly * * @param */public abstract class AbstractAdapter extends BaseAdapter {protected Context context;protected List listData;protected LayoutInflater layoutInflater;public AbstractAdapter(Context context,List listData){this.context = context;this.listData = listData;layoutInflater = LayoutInflater.from(context);}@Overridepublic int getCount() {if(listData!=null){return listData.size();}return 0;}@Overridepublic Object getItem(int position) {if(listData!=null){return listData.get(position);}return null;}@Overridepublic long getItemId(int position) {return position;}public List getListData() {return listData;}public void setListData(List listData) {this.listData = listData;}}
AbstractAdapter 將父類比較有共性的方法重寫,自訂配接器時,只要繼承AbstractAdapter,重寫getView方法就可以了。
3.HolderAdapter
/** * 通用適配器(適合一些常規的適配器) * @author Jenly * * @param */public abstract class HolderAdapter extends AbstractAdapter{public HolderAdapter(Context context, List listData) {super(context, listData);}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {Object holder = null;if(convertView==null){convertView = buildConvertView(layoutInflater);holder = buildHolder(convertView);convertView.setTag(holder);}else{holder = convertView.getTag();}bindViewData(holder,listData.get(position),position);return convertView;}/** * 建立convertView * @param layoutInflater * @return */public abstract View buildConvertView(LayoutInflater layoutInflater);/** * 建立視圖Holder * @param convertView * @return */public abstract Object buildHolder(View convertView);/** * 綁定資料 * @param holder * @param t * @param position */public abstract void bindViewDatas(Object holder,T t,int position);}
HolderAdapter 繼承於上面的AbstractAdapter類,將getView方法進行重寫與抽象,使代碼更加簡潔,用起來更加簡單,只要是繼承於BaseAdapter的自訂配接器類,改為繼承於HolderAdapter 基本上通用,然後只需實現BuildConvertView、buildHolder、bindViewDatas這三個方法。
下面是個自訂的測試配接器,繼承HolderAdapter實現它的三個抽象方法:
public class TestHolderAdapter extends HolderAdapter{public TestHolderAdapter(Context context, List listData) {super(context, listData);}@Overridepublic View buildConvertView(LayoutInflater layoutInflater) {return layoutInflater.inflate(R.layout.activity_list_item, null);}@Overridepublic Object buildHolder(View convertView) {ViewHolder holder = new ViewHolder();holder.tv = (TextView)convertView.findViewById(R.id.tv);return holder;}@Overridepublic void bindViewDatas(Object holder, String t, int position) {((ViewHolder)holder).tv.setText(t);}private static class ViewHolder{TextView tv;}}