1. 程式人生 > >封裝BaseAdapter 實現類中複用

封裝BaseAdapter 實現類中複用

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;
    }