android筆記(一):Adapter寫法優化

wall_j發表於2016-11-01

第一層:一開始寫Adapter的時候,我不考慮重用和inflate之類的問題,只要convertView==null,那我就從xml裡面inflate一個出來。

第二層:後面有一天,我偶然看到別人一篇介紹adapter通用寫法的文章。

通過一個寫一個ViewHolder的實體類,持有item中需要被更改的所有view類,大概類似。

class ViewHolder{
    TextView text1;
    TextView text2;
}
然後在getView中使用該ViewHolder作為一個cache,大概類似如下:

public View getView(int position,View convertView,ViewGroup viewGroup){
    ViewHolder cache;
    if(convertView == null){
        v = LayoutInflater.from(mContext).inflate(R.layout.samplelayout);
        cache = new ViewHolder();
        cache.text1 = v.findViewById(R.id.text1);
        cache.text2 = v.findViewById(R.id.text2);
        convertView.setTag(R.id.tag_cache,cache)
    }else{
        cache = convertView.getTag(R.id.tag_cache);
    }
    ....
}
我第一次看到這種寫法,覺得很奇怪,既然這種寫法是比較通用的,甚至稱得上規範寫法,那麼為什麼不把這鐘寫法直接寫到BaseAdapter中,以省去萬千應用開發者的一段程式碼。

第三層:看到一個同事寫的程式碼,然後又聯想到RecylerView的adapter寫法貌似也很類似,和我當初的想法貌似也有點契合,這湊齊了所有巧合的方法,讓我覺得應該整理下來,免得下次又忘了。

既然Android不幫我們把這段通用程式碼寫到標準裡面,那我們就自己把他整合到我們的基類裡面就好了。

我們的BaseAdapter類似如下:

public abstract class BaseListAdapter<V extends BaseListAdapter.ViewHolder> extends BaseAdapter{
    ...
    public View getView(int position,View convertView,ViewGroup viewGroup){
        V v;
        if(convertView == null){
            v = onCreateViewHolder(viewGroup,getItemType(position));
            convertView = v.itemView;
            convertView.setTag(convertView.getId(),v);
        }else{
            v = (V) convertView.getTag(convertView.getId());
        }
        onBindViewHolder(v,position);
        return convertView;
    }
    ...
    public abstract void onBindViewHolder(V holder, int position);
    public abstract V onCreateViewHolder(ViewGroup parent, int viewType);
    public static class ViewHolder{
        public View itemView;
        public ViewHolder(View itemView){
            this.itemView = itemView;
        }
        protected View findViewById(int id){
            return itemView != null? itemView.findViewById(id):null;     
        }
    }
}
這樣子寫之後在子類Adapter繼承自該BaseListAdapter後就不再需要關心cache以及重用之類的邏輯了,又簡化了一小步,不過程式碼總是在一小步一小步中被優化的。

子類需要做的事情變得非常純粹。

實現生成ViewHolder的onCreateViewHolder方法,以及實現繫結資料到view的onBindViewHolder方法即可。

程式碼參考了小剛童鞋的部分程式碼(未免他看到,此處提一下,哈哈)


相關文章