【问题标题】:How to implement Endless scrolling using StaggeredLayoutManager如何使用 StaggeredLayoutManager 实现无限滚动
【发布时间】:2015-05-18 17:22:26
【问题描述】:

我已经尝试为 LinearLayoutManager 实现无限滚动并且它成功并尝试将 LinearLayoutManager 实现复制到 StaggeredGridLayoutManager 但它不起作用。

我只想获取 firstVisibleItem。

在线性布局管理器中:

int firstVisibleItem = linearLayoutManager.findFirstVisibleItemPosition(int);

但在 StaggeredGridLayoutManager 中是:

int firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(int[])

如何使用 (int) 而不是 (int[]) 获取 firstVisibleItem?

对此有什么好的方法/实现吗?

提前致谢。

【问题讨论】:

    标签: android android-recyclerview endlessscroll staggeredgridlayout


    【解决方案1】:

    我搞定了:

    您可以在 StaggeredGridLayoutManager 中使用两种方法之一:

    1. findFirstVisibleItemPositions(int[])
    2. findFirstCompletelyVisibleItemPositions(int[])

    传递一个空的 int 数组,该数组将使用位置进行初始化,并使用对您有意义的数组。

    private boolean loading = true;
    private int pastVisibleItems, visibleItemCount, totalItemCount;
    
    mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener({
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
    
            visibleItemCount = mLayoutManager.getChildCount();
            totalItemCount = mLayoutManager.getItemCount();
            int[] firstVisibleItems = null;
            firstVisibleItems = mLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
            if(firstVisibleItems != null && firstVisibleItems.length > 0) {
                pastVisibleItems = firstVisibleItems[0];
            }
    
            if (loading) {
                if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                    loading = false;
                    Log.d("tag", "LOAD NEXT ITEM");
                }
            }
        }
    });
    

    【讨论】:

    • 非常感谢这个解决方案。我想要的效果很好。实际上在更新的 AppCompactLibrary 中,他们有一些方法可以做到这一点。但由于某种原因,我无法更新库。所以我被卡住了。你的回答给了我正确的解决方案。非常感谢。
    【解决方案2】:

    这是我对ScrollListener 的实现。

    这是我实现ScrollListener的代码:

    private EndlessScrollListener scrollListener =
        new EndlessScrollListener(new EndlessScrollListener.RefreshList() {
            @Override public void onRefresh(int pageNumber) {
                //Here you can execute server connection or anything else to update data and present with Recycler view
                // Notice: It is sync method
    
            }
        });
    
    recyclerView.addOnScrollListener(scrollListener);
    

    自定义ScrollListener类:

    class EndlessScrollListener extends RecyclerView.OnScrollListener {
        private boolean isLoading;
        private boolean hasMorePages;
        private int pageNumber = 0;
        private RefreshList refreshList;
        private boolean isRefreshing;
        private int pastVisibleItems;
    
    
    
        public EndlessScrollListener(RefreshList refreshList) {
            this.isLoading = false;
            this.hasMorePages = true;
            this.refreshList = refreshList;
        }
    
        @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            StaggeredGridLayoutManager manager =
                (StaggeredGridLayoutManager) recyclerView.getLayoutManager();
    
            int visibleItemCount = manager.getChildCount();
            int totalItemCount = manager.getItemCount();
            int[] firstVisibleItems = manager.findFirstVisibleItemPositions(null);
            if (firstVisibleItems != null && firstVisibleItems.length > 0) {
                pastVisibleItems = firstVisibleItems[0];
            }
    
            if ((visibleItemCount + pastVisibleItems) >= totalItemCount && !isLoading) {
                isLoading = true;
                if (hasMorePages && !isRefreshing) {
                    isRefreshing = true;
                    new Handler().postDelayed(new Runnable() {
                        @Override public void run() {
                            refreshList.onRefresh(pageNumber);
                        }
                    }, 200);
                }
            } else {
                isLoading = false;
            }
        }
    
        public void noMorePages() {
            this.hasMorePages = false;
        }
    
        public void notifyMorePages() {
            isRefreshing = false;
            pageNumber = pageNumber + 1;
        }
    
    
    
        public interface RefreshList {
            void onRefresh(int pageNumber);
        }
    }
    

    【讨论】:

    • 刷新总是正确的,这个方法必须是公开的并且在“onRefresh”中调用
    • @PabloCegarra 你能再解释一下吗?我不明白你是什么意思?侦听器的主要思想是让开发人员知道用户何时触摸列表的末尾。所以这个事件他在'onRefresh()'中得到。还是我错了?
    • 是的,它对我来说就像一个魅力,但这个例子令人困惑,因为 notifyMorePages 不是公开的
    • 它正在工作,但 EndlessScrollListener 构造函数和 RefreshList 并不公开,这就是我遇到问题的原因,我在 Kotlin 中使用它,当我滚动它时它只工作一次它没有工作,任何想法,我做错了什么。我在哪里通知更多页面。
    • @farhana 我已经使用这段代码来加载下一部分数据(这是很久以前的事了),现在还有一个更好的解决方案,我正在使用developer.android.com/topic/libraries/architecture/paging
    【解决方案3】:

    要实现EndlessRecyclerOnScrollListener首先创建EndlessRecyclerOnScrollListener java类

       import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    
    public abstract class EndlessRecyclerOnScrollListener extends RecyclerView.OnScrollListener {
        public static String TAG = EndlessRecyclerOnScrollListener.class.getSimpleName();
        private int scrolledDistance = 0;
        private boolean controlsVisible = false;
    
        private boolean loading = true; // True if we are still waiting for the last set of data to load.
        private int visibleThreshold = 5; // The minimum amount of items to have below your current scroll position before loading more.
    
        private int pastVisibleItems, visibleItemCount, totalItemCount;
    
        private int current_page = 1;
    
        private StaggeredGridLayoutManager mStaggeredGridLayoutManager;
    
        public EndlessRecyclerOnScrollListener(StaggeredGridLayoutManager staggeredGridLayoutManager) {
            this.mStaggeredGridLayoutManager = staggeredGridLayoutManager;
    
        }
    
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
    
            visibleItemCount = recyclerView.getChildCount();
            totalItemCount = mStaggeredGridLayoutManager.getItemCount();
            //firstVisibleItem = mStaggeredGridLayoutManager.findFirstVisibleItemPosition();
            int[] firstVisibleItems = null;
            firstVisibleItems = mStaggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
            if (firstVisibleItems != null && firstVisibleItems.length > 0) {
                pastVisibleItems = firstVisibleItems[0];
            }
    
    
            if (loading) {
                if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                    loading = false;
                    previousTotal = totalItemCount;
                }
            }
            if (!loading && (totalItemCount - visibleItemCount)
                    <= (pastVisibleItems + visibleThreshold)) {
                // End has been reached
    
                // Do something
                current_page++;
    
                onLoadMore(current_page);
    
                loading = true;
            }
    
            if (scrolledDistance > 1 && controlsVisible) {
                controlsVisible = false;
                scrolledDistance = 0;
            } else if (scrolledDistance < -1 && !controlsVisible) {
                controlsVisible = true;
                scrolledDistance = 0;
            }
    
            if ((controlsVisible && dy > 0) || (!controlsVisible && dy < 0)) {
                scrolledDistance += dy;
            }
        }
    
        public abstract void onLoadMore(int current_page);
    
        ;
    }
    

    进入您的活动或片段(此示例用于片段)后使用下一个代码

        RecyclerView mRecyclerView;
    StaggeredGridLayoutManager mStaggeredGridLayoutManager;
    
    private RecyclerView.Adapter adapter;
    
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle saveInstanceState) {
    
            View v = inflater.inflate(R.layout.notices_layout, container, false);
    
            mRecyclerView = (RecyclerView) v.findViewById(R.id.listaNoticias);
     mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(
                    2, //number of grid columns
                    GridLayoutManager.VERTICAL);
    
    //Sets the gap handling strategy for StaggeredGridLayoutManager
            mStaggeredGridLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
    
            mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager);
    
    //initializing our adapter
    adapter = new MyAdapter(list, getContext());
    
    //Adding adapter to recyclerview
    mRecyclerView.setAdapter(adapter);
    
    mRecyclerView.setOnScrollListener(new EndlessRecyclerOnScrollListener(mStaggeredGridLayoutManager) {
                @Override
                public void onLoadMore(int current_page) {
                    // do something...
                    getData(current_page);
                }
            });
    
    return v;
    }
    

    【讨论】:

      【解决方案4】:
      int mSpanCount = 2;
      
      int[] into = new int[mSpanCount];
      
      int firstVisibleItem = staggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0];
      

      【讨论】:

        猜你喜欢
        • 2017-08-16
        • 2023-03-31
        • 2022-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-26
        • 1970-01-01
        • 2017-05-02
        相关资源
        最近更新 更多