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