天天看點

BaseAdapter和Viewholder的抽取(模版設計模式)

為什麼要抽取呢?

因為每次都要寫重複的代碼,寫一次還好寫多了,自然就不合适了
  1. 我們首先觀察,每次都要進行一次設定個數啊,傳回list的對應對象,判斷不為空啊,如下所示:
public int getCount() {
     if (mDatas != null) {
         return mDatas.size();
     }
     return 0;
 }

 public Object getItem(int position) {
     if (mDatas != null) {
         return mDatas.get(position);
     }
     return null;
 }

 public long getItemId(int position) {
     return position;
 }
           
  1. 我們發現可以把這三個方法抽取出來,放到一個我自己的BaseMyAdapter中
public class BaseMyAdapter extends BaseAdapter
           
  1. 可是我們接着又發現資料我們不知道如何擷取到啊...
    每次當我們給listview等設定Adapter的時候都是要new出來,突然我發現可以在構造函數中設定資料,而類型我可以設定成泛型,

    BaseMyAdapter<T>

    類名也要加上泛型
暫時的BaseAdapter算是抽取結束了(暫時),同時我們發現每次都要定義ViewHolder類 這個我們可以抽取嗎?(答案是可以的)
  1. 我們可以首先對這個首頁的holder進行抽取,利用MAC思想,定義一個BaseHolder
  • 我們發現無非每次都是要擷取view,并且添加進tag中
    public abstract class BaseHolder<T> {
    
          public View mRootView;
    
          public BaseHolder() {
              mRootView = initView();
              mRootView.setTag(this);
          }
    
          // 相當于我進行了初始化這個item的布局
          public abstract View initView();
    
          // 我要進行資料的添加和ui的更新
          public abstract void setDatasAndRefreshUI(T datas);
      }
               
    在這裡我們知道到底要加載什麼樣item這個類并不知道,可是又要必須實作,我們則定義成抽象方法,讓具體實作子類完成
  • 這時我們可以進行對BaseAdapter進一步的抽取
    public View getView(int position, View convertView, ViewGroup parent) {
              BaseHolder<T> holder = null;
              if (convertView == null) {
                  holder = getHolder();
              } else {
                  holder = (BaseHolder<T>) convertView.getTag();
              }
              // 添加資料,進行UI界面的重新整理
              holder.setDatasAndRefreshUI(mDatas.get(position));
              return holder.mRootView;
          }
    
          public abstract BaseHolder<T> getHolder();
               
    因為具體要加載哪個view并不知道,這裡我們設定成抽象方法,讓具體的子類進行實作
  • 這時如果要繼承BaseMyAdapter就會變成這個樣子
    private class MyDatasAdapter extends BaseMyAdapter<String> {
          public MyDatasAdapter(List<String> mDatas) {
              super(mDatas);
          }
    
          public BaseHolder<String> getHolder() {
              return new HomeHolder();
          }
      }
               
    代碼中具體的homeHolder如下:
public class HomeHolder extends BaseHolder<String> {

      private TextView mTvtmp1;
      private TextView mTvtmp2;

      public HomeHolder() {
          super();
      }

      public View initView() {
          // 相當于我進行了初始化這個item的布局
          View mRootView = View.inflate(UIUtils.getContext(),
                  R.layout.item_temp_listview, null);
          mTvtmp1 = (TextView) mRootView.findViewById(R.id.item_temp_tv1);
          mTvtmp2 = (TextView) mRootView.findViewById(R.id.item_temp_tv2);
          return mRootView;
      }

      public void setDatasAndRefreshUI(String datas) {
          // 我要進行資料的添加和ui的更新
          mTvtmp1.setText("頭" + datas);
          mTvtmp2.setText("尾巴" + datas);
      }
  }
           
  • 最終BaseHolder:
public abstract class BaseHolder<T> {

      public View mRootView;

      public BaseHolder() {
          mRootView = initView();
          mRootView.setTag(this);
      }

      // 相當于我進行了初始化這個item的布局
      public abstract View initView();

      // 我要進行資料的添加和ui的更新
      public abstract void setDatasAndRefreshUI(T datas);
  }
           
  • 最終BaseMyAdapter:
public abstract class BaseMyAdapter<T> extends BaseAdapter {

      private List<T> mDatas;

      /** 通過構造擷取資料 */
      public BaseMyAdapter(List<T> mDatas) {
          this.mDatas = mDatas;
      }

      public int getCount() {
          if (mDatas != null) {
              return mDatas.size();
          }
          return 0;
      }

      @Override
      public Object getItem(int position) {
          if (mDatas != null) {
              return mDatas.get(position);
          }
          return null;
      }

      public long getItemId(int position) {
          return position;
      }

      public View getView(int position, View convertView, ViewGroup parent) {
          BaseHolder<T> holder = null;
          if (convertView == null) {
              holder = getHolder();
          } else {
              holder = (BaseHolder<T>) convertView.getTag();
          }
          // 添加資料,進行UI界面的重新整理
          holder.setDatasAndRefreshUI(mDatas.get(position));
          return holder.mRootView;
      }

      public abstract BaseHolder<T> getHolder();
  }
           

轉載需注明來源

繼續閱讀