优雅的给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

本篇博客的下载地址

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