打造自己的RecyclerView(二)之下拉刷新和上拉加载更多

上一篇博客记录了如何为RecyclerView添加头布局和脚布局,添加这个有什么用呢,当然主要是为了下拉刷新和上拉加载更多了,不然单独的添加两个布局也没有多大意义。

为RecyclerView添加HeaderView和FooterView传送门

上代码:

首先需要先将HeaderView和FooterView设置为不可见(以HeaderView为例,FooterView原理差不多,一会儿贴代码):

    public void addHeaderView(View view) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        view.setLayoutParams(params);
        view.setVisibility(GONE);

        FixedViewInfo info = new FixedViewInfo();
        info.view = view;
        info.viewType = BASE_HEADER_VIEW_TYPE + mHeaderViewInfos.size();
        mHeaderViewInfos.clear();
        mHeaderViewInfos.add(info);

        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }
然后添加回调方法:

    //定义一些需要用到的变量
    private int lastItem;
    private int firstItem;
    private boolean isLoading = false;
    private boolean isRefreshing = false;
    private OnRefreshListener onRefreshListener;
    private OnLoadMoreListener onLoadMoreListener;

    private OnScrollListener mOnScrollListener1, mOnScrollListener2;

    public interface OnRefreshListener {
        void onRefresh();
    }


关键是下拉刷新和上拉刷新的监听器:
    public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
        this.onRefreshListener = onRefreshListener;
        if (mOnScrollListener1 == null) {
            mOnScrollListener1 = new OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    //当第一个可见item等于JeaderView的个数,并且是未滑动的状态下才会刷新
                    if (firstItem == ((WrapperRecyclerViewAdapter) mAdapter).getHeadersCount()
                            && newState == RecyclerView.SCROLL_STATE_IDLE
                            && !isRefreshing) {
                        //将HeaderView设为可见
                        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
                        params.width = RecyclerView.LayoutParams.MATCH_PARENT;
                        params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
                        getHeaderView(0).setLayoutParams(params);
                        getHeaderView(0).setVisibility(VISIBLE);
                        isRefreshing = true;
                        //调用下拉刷新的方法
                        HeaderRecyclerView.this.onRefreshListener.onRefresh();
                    }
                }

                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    //得到当前第一个可见item
                    firstItem = ((LinearLayoutManager) getLayoutManager()).findFirstVisibleItemPosition();
                }
            };
            this.addOnScrollListener(mOnScrollListener1);
        }
    }

在数据加载完成后,调用两个方法:

    public void setRefreshComplete() {
        //重新将HeaderView设为不可见,并刷新适配器
        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getHeaderView(0).getLayoutParams();
        params.width = 0;
        params.height = 0;
        getHeaderView(0).setLayoutParams(params);
        getHeaderView(0).setVisibility(GONE);
        this.getAdapter().notifyDataSetChanged();
        isRefreshing = false;
    }


让我们看看如何使用:

        hrvTest.setOnRefreshListener(new HeaderRecyclerView.OnRefreshListener() {
            @Override
            public void onRefresh() {
                //模拟下拉刷新
                mHandler.sendEmptyMessageDelayed(1, 3000);
            }
        });


模拟加载数据
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                for (int i = 0; i < 5; i++) {
                    mList.add(0, "onRefresh " + i);
                }
                //数据加载完成后调用RecyclerView中的方法
                hrvTest.setRefreshComplete();
            }
            if (msg.what == 2) {
                for (int i = 0; i < 5; i++) {
                    mList.add("onLoadMore " + i);
                }
                hrvTest.setLoadMoreComplete();
            }
        }
    };


上拉加载更多,原理差不多,直接贴代码:

    public void addFooterView(View view) {
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        view.setLayoutParams(params);
        view.setVisibility(GONE);

        FixedViewInfo info = new FixedViewInfo();
        info.view = view;
        info.viewType = BASE_FOOTER_VIEW_TYPE + mFooterViewInfos.size();
        mFooterViewInfos.clear();
        mFooterViewInfos.add(info);

        if (mAdapter != null) {
            mAdapter.notifyDataSetChanged();
        }
    }

    public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) {
        this.onLoadMoreListener = onLoadMoreListener;
        if (mOnScrollListener2 == null) {
            mOnScrollListener2 = new OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    super.onScrollStateChanged(recyclerView, newState);
                    if (lastItem == mAdapter.getItemCount() - ((WrapperRecyclerViewAdapter) mAdapter).getHeadersCount() - ((WrapperRecyclerViewAdapter) mAdapter).getFootersCount()
                            && newState == RecyclerView.SCROLL_STATE_IDLE
                            && !isLoading) {
                        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) getFooterView(0).getLayoutParams();
                        params.width = RecyclerView.LayoutParams.MATCH_PARENT;
                        params.height = RecyclerView.LayoutParams.WRAP_CONTENT;
                        getFooterView(0).setLayoutParams(params);
                        getFooterView(0).setVisibility(VISIBLE);
                        isLoading = true;
                        HeaderRecyclerView.this.onLoadMoreListener.onLoadMore();
                    }
                }

                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    lastItem = ((LinearLayoutManager) getLayoutManager()).findLastVisibleItemPosition();
                }
            };
            this.addOnScrollListener(mOnScrollListener2);
        }
    }

    public void setLoadMoreComplete() {
        RecyclerView.LayoutParams params = (LayoutParams) getFooterView(0).getLayoutParams();
        params.width = 0;
        params.height = 0;
        getFooterView(0).setLayoutParams(params);
        getFooterView(0).setVisibility(View.GONE);
        this.getAdapter().notifyDataSetChanged();
        isLoading = false;
    }

        hrvTest.setOnLoadMoreListener(new HeaderRecyclerView.OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                //模拟加载更多
                mHandler.sendEmptyMessageDelayed(2, 3000);
            }
        });

不出意外的话,就可以看到下拉和上拉的效果啦。



这是第一次模仿着写一个自定义View,虽然不是自己创造的,不过原理也弄懂了七七八八,也还有点缺陷,就是下拉和上拉没有添加动画,后面会继续优化这个。

在技术的道路上,为自己加油。

源码下载


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值