優雅的給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

本篇博客的下載地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章