1. 程式人生 > >優雅的給RecyclerView新增頭、腳、上拉載入、下拉重新整理

優雅的給RecyclerView新增頭、腳、上拉載入、下拉重新整理

這裡寫連結內容

- **給RcyclerView新增頭和腳**
- **給RcyclerView新增下拉重新整理**
- **給RcyclerView新增上拉載入**

先上兩張效果圖,如下
下拉重新整理和頭部的新增
這裡寫圖片描述

給recyclerview新增頭和腳,主要參考的是鴻洋的部落格Android 優雅的為RecyclerView新增HeaderView和FooterView。它的實現原理是在重寫RecyclerView.Adapter的時候,在外層巢狀一個baseAdapter,所有新增頭和腳的程式碼都是在這個baseAdapter中實現的。

其中關於RecyclerView巢狀主要的一個方法就是getType(),根據不同的型別顯示不同的樣式,從而顯示頭和腳,其實頭和腳都只是item的一種而已,相關程式碼如下:

 @Override
    public int getItemViewType(int position) {
        if(isHeader(position)){
            return mHeaderViews.keyAt(position); //檢視指定位置的鍵
        }else if(isFooter(position)){
            return mFooterViews.keyAt(position-getHeaderCount()-getRealItemCount());
        }else if(isPullToLoading(position)){
            return
BASE_PULL_TO_LOADING; } return adapter.getItemViewType(position-getHeaderCount()); }

頭和腳的新增方法都還是比較簡單。給recyclerView新增下拉重新整理就完全可以用系統提供的下拉重新整理功能,即SwipeRefreshLayout,SwipeRefreshLayout的用法比較簡單,你只需要把它看成是一個Layout就可以,把你需要重新整理的控制元件,如recyclerView新增到佈局下就可以了,然後在程式碼中進行簡單的設定就可以。
相關程式碼如下:

 //給recyclerView新增下拉重新整理(重新整理的顏色可自定義)
layout_swipe_refresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { //更改資料 data.add(0,"下拉重新整理新增的資料"); //這裡的1是新增的頭的個數,因為呼叫系統的重新整理動畫需要傳一個位置引數 helper.notifyItemInserted(1); //重新整理動畫 //關閉下拉重新整理動畫 layout_swipe_refresh.setRefreshing(false); } });

當完成了以上功能後,就剩下上拉載入了,這裡我用 到了recyclerView的滑動監聽來實現。具體就是判斷當recyclerview滑動到底部的時候,顯示上拉載入動畫,當資料發生改變後關閉上拉重新整理動畫,當然,這裡的重新整理動畫也是一item,所以,想要更改重新整理樣式,只需要修改item.xml檔案即可,相關程式碼如下:

public abstract class PullToLoading extends RecyclerView.OnScrollListener {

    private int beforeCount = 0;
    private boolean loading = true; //第一重新整理的時候用
    RecyclerView recyclerView;

//    封裝自動重新整理的程式碼
//    private Handler handler = new Handler(){
//        @Override
//        public void handleMessage(Message msg) {
//            if(msg.what==1){
//                //判斷當顯示了下拉重新整理才關閉重新整理
//                if( ((RecyclerViewHelper) recyclerView.getAdapter()).getPullToLoading()==1){
////                    ((RecyclerViewHelper) recyclerView.getAdapter()).closePullToLoading();
//                }
//            }
//        }
//    };
//    boolean isLoading = true;
//    public PullToLoading() {
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                while (true) {
//                    if (recyclerView != null) {
//                        int total = recyclerView.getLayoutManager().getItemCount();
//                        if (loading) {
//                            loading = false;
//                            beforeCount = total;
//                        }
//                        if (beforeCount < total&&isLoading) {
//                            LogUtil.showLog("11111111111111111111111111");
//                            //發訊息
//                            handler.sendEmptyMessage(1);
//                            beforeCount = total;
//                        }
//                    }
//                }
//            }
//        }).start();
//    }

    /**
     * SCROLL_STATE_TOUCH_SCROLL#手接觸ScrollView觸發一次
     *   SCROLL_STATE_DRAGGING#正在滾動
     *   SCROLL_STATE_IDLE#滑動停止
     * @param recyclerView
     * @param newState
     */
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        //已經加載出來的item數量
        switch (newState) {
            case RecyclerView.TOUCH_SLOP_DEFAULT: //當按下螢幕的時候呼叫
                break;
            case RecyclerView.TOUCH_SLOP_PAGING:  //當快速滑動的時候呼叫
                break;
        }

//        int currentItem = recyclerView.getChildCount(); //載入的item的數量

    }

    private int findMax(int[] lastPositions) {
        int max = lastPositions[0];
        for (int value : lastPositions) {
            if (value > max) {
                max = value;
            }
        }
        return max;
    }


    //每次滑動的時候呼叫,多次觸發
    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        this.recyclerView = recyclerView;
        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        int total = recyclerView.getLayoutManager().getItemCount(); //item的總數
        int lastPosition = -1;
        if (manager instanceof LinearLayoutManager) {
            lastPosition = ((LinearLayoutManager) manager).findLastCompletelyVisibleItemPosition();
        } else if (manager instanceof GridLayoutManager) {
            lastPosition = ((GridLayoutManager) manager).findLastCompletelyVisibleItemPosition();
        } else if (manager instanceof StaggeredGridLayoutManager) {
            int[] lastPs = new int[((StaggeredGridLayoutManager) manager).getSpanCount()];
            ((StaggeredGridLayoutManager) manager).findLastVisibleItemPositions(lastPs);
            lastPosition = findMax(lastPs);
        }
        if (lastPosition == total - 1 && (recyclerView.getChildCount() != total)) { //當最後一個位置等於總的item的個數的時候
            Log.i("TAG","已經到達底部");
            ((RecyclerViewHelper) recyclerView.getAdapter()).showPullToLoading();
            loading(recyclerView);
            //判斷資料發生改變
        }
    }

    /**
     * 滑動到底部呼叫
     */
    public abstract void loading(RecyclerView recyclerView);
}

recyclerView除了可以實現listview的基本可以功能外,它還可以寫成類似ExampleListView的樣式,具體的程式碼,它的實現效果比傳統的ExampleListView更加好看,更加優雅,可以參見ExpandableRecyclerView