1. 程式人生 > >詳解自主實現RecyclerView下拉重新整理、上拉載入、Header、Footer以及swiperefreshlayout的部分講解

詳解自主實現RecyclerView下拉重新整理、上拉載入、Header、Footer以及swiperefreshlayout的部分講解

  年前年後的那段時間比較忙,忙的來忘了寫部落格。最近空閒了,有時間了,來看部落格發現有兩個來月沒有發文章了,對自己的沒有堅持先來幾個鄙視鄙視鄙視,部落格還是要寫的,以後會持續更新。

  廢話少說,網上關於列表控制元件(無論是RecyclerView,還是ListView、GridView等等)下拉進行重新整理的部落格有很多,但是也僅僅只是講了重新整理,關於上拉載入方面要麼條理不清,要麼胡亂貼上,有部分甚至講得狗屁不通(至少我是這麼覺得的)。吐槽完了,那麼怎麼進行重新整理載入呢?本文僅僅以提供一個思路的方式,用一個簡單的demo說一下。

  整體效果圖如下:

  

一、重新整理

  簡單說說下拉重新整理,和很多人用的一樣,使用的是Swiperefreshlayout + Recyclerview的方式實現下拉重新整理。附上Swiperefreshlayout + Recyclerview的佈局檔案,如下。  

                                         

既然說到了SwipeRefreshLayout就多說幾句:

  ⑴SwipeRefreshLayout是Google官方更新的一個widget控制元件,可以實現下拉重新整理的效果。常用下面幾種方法:

swiperefreshlayout.setOnReFreshListener:新增下拉重新整理監聽器

  setColorSchemeColors方法:設定載入圖示的顏色,可以載入多個顏色引數,當然也可以只加載一個

  setProgressBackGroundColorSchemeColor:設定載入圖示的背景顏色,可以載入多個顏色引數,也可以只加載一個

  setRefreshing:顯示或隱藏重新整理進度條,引數為Boolean型,flase使載入圖示消失,true使載入圖示一直顯示

  isFreshing:檢查是否處於重新整理狀態

  首先初始化:

private void initView() {
        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swiprefresh);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);
  }
  接著以一個方法將模擬載入資料封起來(同時將recyclerview載入adapter放在了這個方法內部):
  public void getData(int num){
        for (int i = 0; i < num; i++) {
            list.add(i+"");
        }
        recyclerViewAdapter = new MyRecyclerViewAdapter(getApplicationContext(),list);
        recyclerView.setAdapter(recyclerViewAdapter);
  }
  題外話:其實在任何開發過程中,都應該建立良好開發習慣,將預估會多次使用的程式碼塊封裝成一個類或者一個方法,尚不說設計模式,這樣的程式碼首先給人印象就會很簡潔。

然後在主執行緒中進行一個簡單的模擬重新整理操作:

  private void showAct() {
        getData(num);//在全域性中,num初始化時為41
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                list.removeAll(list);
                num = 41;
                getData(num);
                swipeRefreshLayout.setRefreshing(false);
            }
        });
  }
  重新整理很簡單就是以上所示。

二、載入與自定義Header、Footer
  載入,載入的方式是以自定義一個Footer,然後在Adapter中新增的方式來展示。既然說了Footer,就多一句題外話,demo中有在Adapter中新增一個自滑的ViewPager作為Header。

傻瓜式講解:

  因為採用有普通Item、Footer、Header三種不同展示,所以在Adapter中會有三種不同佈局的ViewHold,Header已經說過是使用的ViewPager,普通Item是TextView,主要給出Footer(載入)的佈局:

  

(1)Adapter

  Adapter中FooterViewHolder展示:

 class FooterViewHolder extends RecyclerView.ViewHolder {

        private final ProgressBar progressBar;
        private final TextView footer_tv;
        private final LinearLayout footerLayout;

        public FooterViewHolder(View itemView) {
            super(itemView);
            footerLayout = (LinearLayout) itemView.findViewById(R.id.footerLayout);
            progressBar = (ProgressBar) itemView.findViewById(R.id.item_footer_progressbar);
            footer_tv = (TextView) itemView.findViewById(R.id.item_footer_tv);
        }
  }

 轉入正題:首先設定判斷普通Item、Header、Footer的標誌位:

  public static final int TYPE_ITEM = 0;
  public static final int TYPE_FOOTER = 1;
  public static final int TYPE_HEADER = 2;

    因為增加了Header、Footer,所以Item的總數是增加了2的,即:

@Override
    public int getItemCount() {
        return list.size() + 2 ;
    }

  同時重寫getItemViewType():

  @Override
  public int getItemViewType(int position) {
        if (position +1 == getItemCount()&& position+1 >= 41) {
            return TYPE_FOOTER;
        } else if (position == 0) {
            return TYPE_HEADER;
        } else {
            return TYPE_ITEM;
        }
  }
   關於載入很重要的一步:position+1>=41。在開發過程中,我們完全可以根據Item的高度,決定列表顯示多少條資料後才出現載入,在這裡我選擇的是41,和前文在Activity中模擬資料的Num數值一樣,也就是當列表出現第41條資料的時候,出現載入。

  在OnCreateViewHolder()中進行判別:

  

  接著在全域性和OnBindViewHolder()中進行操作:

  //初始化載入時的狀態
  private int load_more_status = 0;
 //判斷是否正在載入
  public static final int PULL_LOAD_MORE = 0;
  public static final int LOADING_MORE = 1;
  @Override
  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ItemViewHolder) {
            //普通Item操作
        } else if (holder instanceof FooterViewHolder) {//Footer即載入操作
            ((FooterViewHolder) holder).footerLayout.setVisibility(View.VISIBLE);
            switch (load_more_status) {
                case PULL_LOAD_MORE:
                    ((FooterViewHolder) holder).footer_tv.setText("上拉可載入更多");
                    break;
                case LOADING_MORE:
                    ((FooterViewHolder) holder).progressBar.setVisibility(View.VISIBLE);
                    ((FooterViewHolder) holder).footer_tv.setText("正在載入");
                    break;
            }
        } else if (holder instanceof HeaderViewHolder) {
           //Header中的操作
        }
  }

    再在Adapter中定義一個改變載入狀態位的方法(後面會用到):

  

  以上就是Adapter中操作.回到Activity.

(2)Activity

  設定的是每進行一次載入,多出10條資料,並且每次改變載入狀態。

 //表示最後一個Item
   private int lastVisibleItem;
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
      @Override
      public void onScrollStateChanged(final RecyclerView recyclerView, int newState)   {           super.onScrollStateChanged(recyclerView, newState);
        if (lastVisibleItem +1 >= 40){
          recyclerViewAdapter.changeLoadMoreStatus(MyRecyclerViewAdapter.LOADING_MORE);
           new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
             num = 10;
             getData(num);
             recyclerViewAdapter.changeLoadMoreStatus(MyRecyclerViewAdapter.PULL_LOAD_MORE);
            }
           },1000);
        }
      }

      @Override
      public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
          super.onScrolled(recyclerView, dx, dy);
          lastVisibleItem = linearLayoutManager.findLastCompletelyVisibleItemPosition();
      }
  });

這樣即可。