1. 程式人生 > >recyclerview簡析,點選事件實現簡析

recyclerview簡析,點選事件實現簡析

RecyclerView簡介

RecyclerView是Android5.0提出的UI控制元件,通常用來代替傳統的ListView。
其官方給出的定義如下:

A flexible view for providing a limited window into a large data set.

釋義:靈活的檢視提供一個有限的視窗變成一個大資料集。

從定義可以明白,Flexible(可擴充套件性) 是RecyclerView 顯著的特點。

在使用RecyclerView的時候,需要在專案的build.gradle 中新增相應依賴庫:

compile 'com.android.support:recyclerview-v7:24.2.1'

ListVIew 與 RecyclerView 的簡單對比

  • 相同點:

    • 由於子佈局是被ListView(RecyclerView)所包裹著,所以在獲取子佈局檔案的View物件的時候必須呼叫
      View view = LayoutInflater.from(getContext()).inflate(resourceId,parent,flase);

    • 需要自定義 Adapter (介面卡)來對所需要的顯示的資料進行處理。並藉由此介面卡,把資料按需求的顯示到RecylerView 。

  • 優缺點對比:

    • ListView 相比 RecyclerView 優點:
      • 擁有addHeaderView(),addFooterView()新增頭檢視和尾檢視。
      • 通過“android:divider”設定自定義分割線。
      • 擁有setOnItemClickListener() 和 setOnItemLongClickListener()設定點選事件和長按事件。

藉由以上的這些方法,在RecyclerView 都沒有直接可用的介面,所以再實現以上功能的時候,運用ListView比較合適。

  • RecyclerView 的優點

    • 預設實現View 的複用,不需要類似的If(convertView == null) 的判斷實現前提。
    • 回收機制更加完善。
    • 預設支援區域性重新整理。
    • 容易實現新增Item,刪除Item的動畫效果
    • 容易實現拖拽、側滑刪除等功能。
  • 區別之一:

    • RecyclerView 將 ListView 中的 getView()功能拆分成了onCreateViewHolder() 和 onBinViewHolder()

RecyclerView 的 Adapter 實現相對於 ListView 繁瑣,所以RecyclerView適合運用於,每個子佈局是複雜的綜合佈局的情形。
而相對的若是顯示的子佈局為簡單的TextVIew或ImagView佈局,則使用ListView會更簡單,高效。

RecyclerView 的四大組成

  • Adapter : 為 Item 提供資料
  • Layout Manager : Item 的佈局
    • 佈局形式:
    • LayoutManager :預設為縱向佈局
    • LayoutManager.HORIZONTAL :橫向佈局
  • Item Animator:新增、刪除 Item 動畫
  • Item Decoration : Item 之間的 Divider(間隔線)

RecyclerView 的簡單實現

  • 建立 Adapter(介面卡) :

    • 主要功能是為了 RecyclerView 提供資料 ,簡單的實現如下:
      建立一個繼承RecyclerView.Adapter < DataAdapter.ViewHolder>的 Adapter 類,(其中的ViewHolder是DataAdapter的一個內部實現類)
      static class ViewHolder extends RecyclerView.ViewHolder

    • 建立ViewHolder 內部實現類:讓該內部類繼承RecyclerView.ViewHolder,具體實現細則與ListView中的ViewHolder一樣。

    • 建立父佈局快取物件,子佈局各個控制元件的空物件;藉由重寫ViewHolder方法,利用傳入的父佈局物件itemView,給各個控制元件的空物件載入實際的內容:

      public ViewHolder(View itemView) {
              super(itemView);
      
              //用來儲存子項最外層佈局的例項
              DataView = itemView;
              //取Image和Text View的ID 進行例項化物件。
              DataImage = (ImageView) itemView.findViewById(R.id.image);
              DataName = (TextView) itemView.findViewById(R.id.name);
          }

    (Data作為資料儲存類,存放你想顯示的資料)

    • 在 DataAdapter 中需要實現以下三個方法

      • DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType):用於對映Item Layout ID,並建立ViewHolder物件進行返回,還可以新增點選事件的處理。

      • void onBindViewHolder(WeatherAdapter.ViewHolder holder, int position):為holder設定指定資料(即為所選定的子佈局中的Item設定希望顯示的引數)

      • int getItemCount():返回加入Item的個數,等同一個計數器。
    • 基本的Adapter實現例項參考如下:
       public class DataAdapter extends RecyclerView.Adapter< WeatherAdapter.ViewHolder > {

        private List<Data> mDataList;

        static class ViewHolder extends RecyclerView.ViewHolder {
        View DataView;
        ImageView DataImage;
        TextView DataName;

        public ViewHolder(View itemView) {
            super(itemView);

            //用來儲存子項最外層佈局的例項
            DataView = itemView;
            //取Image和Text View的ID 進行例項化物件。
            DataImage = (ImageView) itemView.findViewById(R.id.image);
            DataName = (TextView) itemView.findViewById(R.id.name);
        }
    }

    public DataAdapter(List<Data> DataList) {
        mDataList = DataList;
    }

    @Override
    public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        /**
         * 用inflate載入自定義的檢視 weather_itme佈局檔案,也稱為layout的對映
         *三個引數的含義:
         * 1.想要擴充套件的佈局的資源ID
         * 2.將作為擴展布局父項的ViewGroup
         * 3.指示是否應該在擴充套件期間將擴展布局附加至root的布林值
         */

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itme, parent, false);

        //建立佈局快取物件,最後返回
        final ViewHolder holder = new ViewHolder(view);

        return holder;
    }

    /**
     * 對RecyclerView子項的資料進行復制,會在每個子項被滾動到螢幕內的時候執行
     *      再將資料設定到ViewHolder的IMageView和TextView當中
     * @param holder  ViewHolder的例項
     * @param position 用於得到當前項的Weather例項
     */
    @Override
    public void onBindViewHolder(DataAdapter.ViewHolder holder, int position) {

        Data data = mDataList.get(position);
        holder.DataImage.setImageResource(data.getImageId());
        holder.DataName.setText(data.getName());

    }

    /**
     *
     * @return 返回RecyclerView一共有多少子項,直接返回資料來源的長度
     */
    @Override
    public int getItemCount() {
        return mDataList.size();
        }
    }

RecyclerView 點選事件的實現

  • 實現思路:

  • (通常把點選事件設定在Adapter的onCreateViewHolder 方法中,使得在剛載入資料的時候就實現了子Item的點選事件)

  • 獲取包裹子Item的父佈局View物件。

  • 利用 View 物件對子Item中所需要設定點選事件的控制元件例項新增設定點選監聽。

  • 在監聽事件中,實現OnClick(View view)對點選事件的具體操作。

  • 簡單的實現形式可參照下:
//給父佈局整個佈局設計點選事件
        holder.weatherView.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition(); 
                //判斷其點選的是哪一個模組 返回它的的下標
                weather Weather = mWeatherList.get(position);
                //通過返回的下標,取到其名稱
                Toast.makeText(view.getContext(), "you clicker view  " + Weather.getName(), Toast.LENGTH_SHORT).show();
            }
        });

        //給父佈局中的子控制元件ImageView 設定點選事件
        holder.weatherImage.setOnClickListener(new View.OnClickListener(){

            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                weather Weather = mWeatherList.get(position);
                Toast.makeText(view.getContext(), "you clicker image  " + Weather.getName(), Toast.LENGTH_SHORT).show();
            }
        });

參考資料