轉載請標明出處:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自【張鴻洋的博客】
注:本文內容基本基於鴻洋大神的博客,地址在上面,可以自行閱讀。
1.通用Adapter(針對ListView,GridView)
由於作者水平有限,參考大神的博客,自己試着寫了寫,目前運用在listview和gridview中,對於recycleView和Viewpager的兼容還是不行的,不過大神博客裏上傳到Git上的那個版本是支持recycleview的,至於viewpager,個人觀點,應該可以整合到一起,就會變成一個全通用的Adapter了。之所以這麼說是因爲之前嘗試過一次,公用一個adapter,實現baseadapter,繼承pageradapter,所有需要重寫的方法都重寫,當時只能過做到簡單的顯示,後來就放在一邊就沒繼續研究,之後有時間會嘗試寫一寫。
2.代碼
具體的內容大神的博客裏已經將的很詳細了,而且對於經常寫adapter的人來說閱讀起來並不費勁,我就把我自己寫過的總體貼一下,有問題歡迎指出。
public class ViewHolder extends RecyclerView.ViewHolder{
private final SparseArray<View> mViews;
private View mConvertView;
private int mPosition;
private int mlayoutId;
private Context mContext;
private ViewHolder(Context context,View itemView,ViewGroup parent,int position){
super(itemView);
mContext=context;
mConvertView=itemView;
mPosition=position;
mViews=new SparseArray<View>();
mConvertView.setTag(this);
}
//獲得ViweHolder對象
public static ViewHolder get(Context context,View convertView,ViewGroup parent,int layoutID,int position){
if(convertView==null){
View itemView=LayoutInflater.from(context).inflate(layoutID, parent,false);
ViewHolder viewHolder = new ViewHolder(context, itemView, parent, position);
viewHolder.mlayoutId=layoutID;
return viewHolder;
}else{
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.mPosition=position;
return holder;
}
}
public <T extends View> T getView(int viewId){
View view=mViews.get(viewId);
if(view==null){
view=mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T)view;
}
public View getConvertView(){
return mConvertView;
}
//設置各種輔助方法
public ViewHolder setText(int viewId,String text){
TextView view=getView(viewId);
view.setText(text);
return this;
}
public ViewHolder setImageResource(int viewId,int drawableId){
ImageView view=getView(viewId);
view.setImageResource(drawableId);
return this;
}
public ViewHolder setImageBitmap(int viewId,Bitmap bitmap){
ImageView view=getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
}
這次代碼中基本沒有註釋,因爲並不難,我寫的是參照大神在git上的最新的支持recycleview的版本的,可能跟大神博客裏的有些不一樣,不過基本上原理是一樣的。
關於寫通用的adapter總結看來主要是針對這幾方面:
1.繼承basedapter,把一些常用的,基本沒有改變的東西都先寫好。主要的技巧就是用到了一個泛型,解決了list集合中不同對象的困擾。
2.ViewHolder的寫法,大神的博客中也說得很詳細了,利用一個SparseArray來保存view對象,SparseArray大家可以把它看做是一個Map,只不過key只能是integer,實際上那SparseArray底層的實現方式是雙數組,跟我們平時遇到的都有點不一樣,它是一個數組存放key,一個數組存放Value。貼一下源碼。
<span style="font-size:18px;">public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
private boolean mGarbage = false;
private int[] mKeys;
private Object[] mValues;
private int mSize;
/**
* Creates a new SparseArray containing no mappings.
*/
public SparseArray() {
this(10);
}
/**
* Creates a new SparseArray containing no mappings that will not
* require any additional memory allocation to store the specified
* number of mappings.
*/
public SparseArray(int initialCapacity) {
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);
mKeys = new int[initialCapacity];
mValues = new Object[initialCapacity];
mSize = 0;
}</span>
可以看出來,是雙數組結構,這樣更便於查找,至於其他的增刪改查方面的大家可以自行去看一下,個人感覺跟arraylist的實現差不多。
3.ViewHolder中對於各種控件屬性的賦值方法,個人感覺能夠想到這一點的人真是太聰明瞭,真不知道最開始是怎麼想到的。在ViewHolder中封裝了大部分常用控件的設置方法,這樣真的就是把adapter精簡到極致了,寫一個adapter只需要一句話。
4.viewholder中對於監聽器的設置,這是在大神發在git上的最新的holder中看到的,封裝了三個常用的ontouch,onclick,onlongclick方法,可以直接調用。
5.在大神的文檔中還有這樣的兩個東西MultiItemCommonAdapter和MultiItemTypeSupport,這個是用來處理不同itemType的時候使用的,最常見的就是聊天界面左右不同的item了。大家可以自行參考。
3.總結
記得第一次看大神這個文章的時候感覺,**,居然還可以這樣?再一看是2014年的文章。頓時感覺自己要努力的地方還有很多啊!準備下一篇寫一寫關於RecycleView的文章,看到大家現在都用這個,準備研究研究,對於CommonAdapter,個人感覺能簡化的就這麼多了,也會嘗試一下和pageradapter整合,不過現在都是viewpager結合fragment用,適配器也採用的是FragmentPageAdapter,這個整合難度有點大,不過個人認爲是可行了,因爲需要的方法是不同的,也不相互干擾,應該沒問題。還是貼一下CommonAdapter的代碼吧。自己也再看一遍。嗯嗯。
public abstract class CommonAdapter<T> extends BaseAdapter{
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected int layoutID;
public CommonAdapter(Context context,List<T> mDatas,int layoutID){
mInflater=LayoutInflater.from(context);
this.mContext=context;
this.mDatas=mDatas;
this.layoutID=layoutID;
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public T getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=ViewHolder.get(mContext, convertView, parent, layoutID, position);
convert(viewHolder,getItem(position));
return viewHolder.getConvertView();
}
public abstract void convert(ViewHolder viewHolder, T item) ;
}
基本上就是常用的方法,不同的就是泛型和getView(),並不難。
文尾附上大神的項目,發表在Git上的,有興趣的可以下下來看看,或者留郵箱。關於recycleView,百度recycleview jar 包,有很多。(剛試了下自己寫的,炸了,一直在報NoClassDefFounfError 錯誤,不報錯誤就是一直在deBug,啊啊啊,要命了。)剛嘗試下 去掉RecycleView的繼承關係就可以了。看來recycleview使用還是有很多需要學的啊。
添加了多種Item類型的支持,源碼地址:https://github.com/hongyangAndroid/base-adapter .