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