Android 用SwipeRefreshLayout+Recy

作者: SwitchLife | 来源:发表于2018-04-10 10:21 被阅读355次

开篇

  工作闲暇之余,用SwipeRefreshLayout+RecyclerView倾心打造了一个下拉刷新控件分享给童鞋们。我给此组件命名为SwipeRefreshRecyclerView
  这是我的另一篇文章:打造类似SwipeRefreshLayout的下拉刷新控件

屏幕截图

SwipeRefreshRecyclerView之亮点:

  • 支持下拉刷新(可开关)
  • 支持下拉加载更多(可开关)
  • 支持自定义空列表视图(EmptyView)
  • 可自定义加载更多(包括视图LoadMoreView、动画、逻辑)
  • 支持各种LayoutManager(仅限于VERTICAL方向)的RecyclerView:LinearLayoutManagerGridLayoutManagerStaggeredGridLayoutManager
  • 纯代码封装、简洁清晰高性能、使用方便

立即体验

扫描以下二维码下载体验App(从0.2.3版本开始,体验App内嵌版本更新检测功能):


JSCKit库传送门:https://github.com/JustinRoom/JSCKit

源码简析

SwipeRefreshRecyclerView关键逻辑(请参阅以下代码里的注释):

        //下拉刷新监听
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                isLoading = true;
                if (customRefreshListener != null) {
                    customRefreshListener.onRefresh();
                }
            }
        });

        recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
                RecyclerView.Adapter adapter = recyclerView.getAdapter();
                if (layoutManager == null || adapter == null) {
                    swipeRefreshLayout.setEnabled(false);
                    return;
                }

                boolean isFirstItemVisiable;
                boolean isLastItemVisiable;
                int itemCount = adapter.getItemCount();
                //GridLayoutManager是继承LinearLayoutManager的。
                if (layoutManager instanceof LinearLayoutManager) {
                    LinearLayoutManager linearLayoutManager = (LinearLayoutManager) layoutManager;
                    //竖直方向,不可下拉刷新,也不可上拉加载更多
                    if (linearLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL){
                        swipeRefreshLayout.setEnabled(false);
                        return;
                    }
                    //判断是否空列表或者已下拉至列表顶部
                    isFirstItemVisiable = (itemCount == 0 || linearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0);
                    //判断是否上拉至列表底部
                    isLastItemVisiable = linearLayoutManager.findLastCompletelyVisibleItemPosition() + 1 == itemCount;
                } else if (layoutManager instanceof StaggeredGridLayoutManager) {
                    StaggeredGridLayoutManager staggeredGridLayoutManager = (StaggeredGridLayoutManager) layoutManager;
                     //竖直方向,不可下拉刷新,也不可上拉加载更多
                    if (staggeredGridLayoutManager.getOrientation() == LinearLayoutManager.HORIZONTAL){
                        swipeRefreshLayout.setEnabled(false);
                        return;
                    }
                    int[] firstItemPositions = staggeredGridLayoutManager.findFirstCompletelyVisibleItemPositions(null);
//                    Log.i(TAG, "onScrolled: " + Arrays.toString(firstItemPositions));
                    //判断是否空列表或者已下拉至列表顶部
                    isFirstItemVisiable = itemCount == 0 || (firstItemPositions.length > 0 && firstItemPositions[0] == 0);
                    int[] lastItemPositions = staggeredGridLayoutManager.findLastCompletelyVisibleItemPositions(null);
                    //判断是否上拉至列表底部
                    isLastItemVisiable = lastItemPositions.length > 0 && (lastItemPositions[lastItemPositions.length - 1] + 1 == itemCount);
                } else {
                    return;
                }
                swipeRefreshLayout.setEnabled(isRefreshEnable() && isFirstItemVisiable);

                if (isLoading || !isLoadMoreEnable() || !isHaveMore || !isLastItemVisiable)
                    return;

                //处理加载更多的动画以及逻辑
                if (customRefreshListener != null) {
                    isLoading = true;
                    //show your custom loading more animation.
                    if (customLoadMoreAnimationListener != null)
                        customLoadMoreAnimationListener.onLoadMoreStartAnim(SwipeRefreshRecyclerView.this, customRefreshListener);
                    else
                        showScrollUpAnim();
                }
            }
        });

公共方法

用法

    int pageSize = 24;//一页最多可显示的数据数
    int pageIndex = 1;//页码

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_swip_recycler_view);

        swipeRefreshRecyclerView = findViewById(R.id.swipe_recycler_view);
        //添加LayoutManager
//        swipeRefreshRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        swipeRefreshRecyclerView.setLayoutManager(new GridLayoutManager(this, 2, RecyclerView.VERTICAL, false));
//        swipeRefreshRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, RecyclerView.VERTICAL));
        //添加ItemDecoration
        DividerItemDecoration decoration = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
        decoration.setDrawable(getResources().getDrawable(R.drawable.item_decoration_shape));
        swipeRefreshRecyclerView.getRecyclerView().addItemDecoration(decoration);
        //
        swipeRefreshRecyclerView.getSwipeRefreshLayout().setColorSchemeColors(0xFF3F51B5, 0xFF303F9F, 0xFFFF4081, Color.CYAN);
        //设置自定义的emptyView
        int topMargin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 64, getResources().getDisplayMetrics());
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.CENTER_HORIZONTAL;
        params.topMargin = topMargin;
        swipeRefreshRecyclerView.setEmptyView(createEmptyView(), params);
        //设置自定义的loadMoreView
        swipeRefreshRecyclerView.setLoadMoreView(createLoadMoreView());
        //添加刷新或者加载更多监听
        swipeRefreshRecyclerView.setCustomRefreshListener(new SwipeRefreshRecyclerView.OnCustomRefreshListener() {
            @Override
            public void onRefresh() {
                pageIndex = 1;
                //模拟请求网络数据
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeRefreshRecyclerView.refreshComplete();
                        List<Banner> banners = getRandomBanners();
                        adapter.setItems(banners);
                        //是否还有下一页数据
                        swipeRefreshRecyclerView.setHaveMore(banners.size() >= pageSize);
                        //是否显示empty view
                        swipeRefreshRecyclerView.showEmptyViewIfNecessary();
                    }
                }, 3000);

            }

            @Override
            public void onLoadMore() {
                pageIndex ++;
                //模拟请求网络数据
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        swipeRefreshRecyclerView.loadMoreComplete();
                        List<Banner> banners = getRandomBanners();
                        adapter.addItems(banners);
                        //是否还有下一页数据
                        swipeRefreshRecyclerView.setHaveMore(banners.size() >= pageSize);
                    }
                }, 3000);
            }
        });
        //自定义“加载更多” 的动画(或逻辑)。请参照SwipeRefreshRecyclerView默认的动画(或逻辑):showScrollUpAnim()、showScrollDownAnim()
        //如果只用SwipeRefreshRecyclerView默认的动画(或逻辑)。不设置OnCustomLoadMoreAnimationListener或者设置为null即可。
/*
        swipeRefreshRecyclerView.setCustomLoadMoreAnimationListener(new SwipeRefreshRecyclerView.OnCustomLoadMoreAnimationListener() {
            @Override
            public void onLoadMoreStartAnim(@NonNull final SwipeRefreshRecyclerView swipeRefreshRecyclerView, final SwipeRefreshRecyclerView.OnCustomRefreshListener refreshListener) {
                final SwipeRefreshLayout layout = swipeRefreshRecyclerView.getSwipeRefreshLayout();
                final View loadMoreView = swipeRefreshRecyclerView.getLoadMoreView();
                // TODO: 4/9/2018
            }

            @Override
            public void onLoadMoreCompleteAnim(@NonNull final SwipeRefreshRecyclerView swipeRefreshRecyclerView, final SwipeRefreshRecyclerView.OnCustomRefreshListener refreshListener) {
                final SwipeRefreshLayout layout = swipeRefreshRecyclerView.getSwipeRefreshLayout();
                final View loadMoreView = swipeRefreshRecyclerView.getLoadMoreView();
                // TODO: 4/9/2018
            }
        });
*/
        adapter = new LinearAdapter();
        //设置适配器
        swipeRefreshRecyclerView.setAdapter(adapter);
        //300毫秒后自动刷新
        swipeRefreshRecyclerView.refreshDelay(300);
    }

篇尾

  如果您觉得还不错的话,给个star(或加个关注)啰!我是JustinRoomQQ:1006368252

新的数学方法和概念,常常比解决数学问题本身更重要。 —— 华罗庚

相关文章

网友评论

  • 月映长安:感谢分享
    SwitchLife:@JustinRoom 不过不影响正常使用:blush:
    SwitchLife:此控件加载更多默认动画有一点点缺陷:就是在网络接口快速返回数据时动画有点快,赶完中秋项目后我在优化下。
  • 4b01863fd657:支持一下
    SwitchLife:@liuly0218 谢谢! 😊

本文标题:Android 用SwipeRefreshLayout+Recy

本文链接:https://www.haomeiwen.com/subject/xdlghftx.html