封裝BaseAdapter 實現類中複用
阿新 • • 發佈:2019-01-11
1.Adapter複用,專案中需要寫很多的 adapter 介面卡 重複程式碼,就想著可以進行程式碼複用,減少重複碼程式碼的時間。
2.參照之前的版本進行優化。先貼上 版本1程式碼。
public abstract class NyBaseAdaper<T> extends BaseAdapter {
protected List<T> list = new ArrayList<>();
protected Context context;
protected LayoutInflater mInflater;
protected NyBaseAdaper(Context context, List<T> list) {
this.list = list;
this.context = context;
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
if (list == null) {
return 0;
} else {
return list.size();
}
}
@Override
public Object getItem(int position) {
return list != null ? list.get(position) : 0;
}
@Override
public long getItemId(int position) {
return position;
}
}
繼承Baseadapter 進行,使用的泛型符號,進行型別限制。將佈局填充器初始化進去。讓子類方便呼叫。這裡只複寫了 三個的方法。(為什麼不在這裡複寫 getview()? )
因為 getview()需要進行處理的邏輯為了減少耦合,在另一個類中單獨處理
package widget.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
/**
* @author weichyang
* 2016/4/12
*/
public abstract class NyCommonAdapter<T> extends NyBaseAdaper<T> {
private LayoutInflater mInflater;
protected NyCommonAdapter(Context context, List<T> list) {
super(context, list);
mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Object viewHolder = null;
if (convertView == null) {
convertView = builderView(mInflater);
viewHolder = builderHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
builderData(viewHolder, position);
return convertView;
}
/**
* 填充資料
*
* @param viewHolder
* @param position
*/
protected abstract void builderData(Object viewHolder, int position);
/**
* 構造viewholder
*
* @param convertView
* @return
*/
protected abstract NyCommonAdapterTest.ViewHolder builderHolder(View convertView);
/**
* 初始化view
*
* @param inflater
* @return
*/
public abstract View builderView(LayoutInflater inflater);
/**
* 進行adapter更新
*
* @param isRefresh
* @param list
*/
public void refreshData(boolean isRefresh, List<T> list) {
if (isRefresh) {
list.addAll(list);
} else {
list.clear();
}
}
}
就是簡單設定,將一些填充佈局和填充資料的方法 讓不同的adapter 自己實現,這裡只是將處理的方法抽取出來,達到複用的目的。
Eg:唯一的缺點就是Viewholder 需要在類中 重新定義。
埋了這個伏筆。引出 version2
既然是為了方便才進行封裝的。要是封裝後變的複雜了。豈不是多此一舉了。然後進行version 2改版。在vhTools 基礎上進行擴充套件(參考 github 上的 commonAdapter進行優化)
**
* 通用適配ViewHolder工具類
*
* @ClassName: ViewHolderTools
* @Description: 用法參考 http://mobile.51cto.com/aprogram-475335.htm
* @author seven7fly
* @date 2015-11-30 下午2:28:42
*
*/
public class VhTools {
@SuppressWarnings("unchecked")
public static <T extends View> T get(View view, int id) {
SparseArray<View> viewHolder = (SparseArray<View>) view.getTag();
if (viewHolder == null) {
viewHolder = new SparseArray<View>();
view.setTag(viewHolder);
}
View childView = viewHolder.get(id);
if (childView == null) {
childView = view.findViewById(id);
viewHolder.put(id, childView);
}
return (T) childView;
}
}
現在優化的點是,viewholder 需要 對viewholder之中的操作進行封裝,並且具有 快取複用的效果。
程式碼片段:如下
**
* @author weichyang
* 2016/4/12
*/
public class ViewHolder {
/**
* ViewHolder實現類,橋接模式適配AbsListView與RecyclerView的二維變化
*/
ViewHolderImpl mHolderImpl;
/**
* @param itemView
*/
ViewHolder(View itemView) {
mHolderImpl = new ViewHolderImpl(itemView);
}
/**
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T findViewById(int viewId) {
return mHolderImpl.findViewById(viewId);
}
public Context getContext() {
return mHolderImpl.mItemView.getContext();
}
/**
* 獲取GodViewHolder
*
* @param convertView
* @param parent
* @param layoutId
* @return
*/
public static ViewHolder get(View convertView, ViewGroup parent, int layoutId) {
ViewHolder viewHolder = null;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
return viewHolder;
}
這樣可以實現 快取複用。然後讓 convertView 傳遞給 ViewHolderImpl (為什麼傳給ViewHolderImpl ,無非就是為了進行程式碼解耦,便於擴充套件),注意看findviewById()
是不是和 VhTools 一樣進行id 和 view 快取。進行遍歷查詢。根據結果執行不同的邏輯
public class ViewHolderImpl {
/**
* 快取子檢視,key為view id, 值為View。
*/
private SparseArray<View> mCahceViews = new SparseArray<View>();
/**
* Item View
*/
View mItemView;
/**
* @param itemView
*/
ViewHolderImpl(View itemView) {
mItemView = itemView;
}
public View getItemView() {
return mItemView;
}
/**
* @param viewId
* @param <T>
* @return
*/
public <T extends View> T findViewById(int viewId) {
View target = mCahceViews.get(viewId);
if (target == null) {
target = mItemView.findViewById(viewId);
mCahceViews.put(viewId, target);
}
return (T) target;
}