为什么findLastCompletelyVisibleItemPosition()返回-1?

时间:2016-12-09 06:31:15

标签: android android-recyclerview

我正在尝试使用片段中的分页来进行无尽的回收视图  但面临的问题如下。

  1. findLastCompletlyVisibleItemPosition()或findFirstCompletelyVisibleItemPosition()仅返回-1。
  2. 如果setNestedScrollingEnabled(false),则onScrollStateChanged无法正常工作
  3. 以下是我的代码示例。 `

            recyclerView = (RecyclerView) view.findViewById(R.id.recycler1);
    
            //recyclerView.setNestedScrollingEnabled(false);                                              // Smooth Scrolling
             mLayoutManager = new LinearLayoutManager(getActivity());
    
            lastVisiblePosition = mLayoutManager.findLastVisibleItemPosition();
            firstVisibleItemPosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
            Log.i("sandi", String.valueOf(firstVisibleItemPosition));
            load = new LoadAdapter(getActivity(), grid_list);
            recyclerView.setLayoutManager(mLayoutManager);
            recyclerView.setItemAnimator(new DefaultItemAnimator());
            recyclerView.setAdapter(load);
            mProgressDialog.dismiss();
    
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                    int threshold =1;
                    int count = recyclerView.getChildCount();
    
    
    
                    Log.i("sand", String.valueOf(count));
    
                    if (newState == SCROLL_STATE_IDLE ) {
                        if (lastVisiblePosition >= count
                                - threshold) {
                            // Execute LoadMoreDataTask AsyncTask
    
                            Log.i("sand","stopped");
                            new LoadMoreDataTask().execute();
                        }
                    } else {
                        Log.i("sand","not stopped");
                    }
                }
    
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                }
            });
        }
    

    修改
    这个问题的解决方案在评论部分。

3 个答案:

答案 0 :(得分:3)

查看LinearLayoutManager

中的第1732至1747行
/**
 * Returns the adapter position of the last fully visible view. This position does not include
 * adapter changes that were dispatched after the last layout pass.
 * <p>
 * Note that bounds check is only performed in the current orientation. That means, if
 * LayoutManager is horizontal, it will only check the view's left and right edges.
 *
 * @return The adapter position of the last fully visible view or
 * {@link RecyclerView#NO_POSITION} if there aren't any visible items.
 * @see #findLastVisibleItemPosition()
 * @see #findFirstCompletelyVisibleItemPosition()
 */

public int findLastCompletelyVisibleItemPosition() {
    final View child = findOneVisibleChild(getChildCount() - 1, -1, true, false);
    return child == null ? NO_POSITION : getPosition(child);
}

如果child为空,则NO_POSITION为-1。

你在做什么:

在设置适配器之前,您正在调用以下内容。没有可用的视图,所以你有-1。

lastVisiblePosition = mLayoutManager.findLastVisibleItemPosition();
firstVisibleItemPosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();

你应该做什么:

当您的适配器视图完全填充时,您可以拥有findLastVisibleItemPositionfindFirstCompletelyVisibleItemPosition。首先设置你的适配器,而不是像

那样获得你的位置
load = new LoadAdapter(getActivity(), grid_list);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(load);
mProgressDialog.dismiss();
// adapter is set now you may have your positions
lastVisiblePosition = mLayoutManager.findLastVisibleItemPosition();
firstVisibleItemPosition = mLayoutManager.findFirstCompletelyVisibleItemPosition();
Log.i("sandi", String.valueOf(firstVisibleItemPosition));

答案 1 :(得分:0)

如果您在recyclerview内使用NestedScrollView,则不会触发recyclerView.addOnScrollListener。我在尝试实现分页时也想到了这一点。而不是我已经为NestedScrollView实现了onScrollChangeListener并使用以下代码完成了这个技巧:

private void implementScrollListener() {

    //Scroll Listener for nestedScrollView. Note that it is used for pagination when user reaches the bottom.

    if(nestedScrollView != null){

        nestedScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
            @Override
            public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

                if (scrollY > oldScrollY) {
                    //Scrolling down
                }
                if (scrollY < oldScrollY) {
                    //Scrolling up
                }

                if (scrollY == 0) {
                    //Reaches to the top
                }

                if (scrollY < (v.getChildAt(0).getMeasuredHeight() - v.getMeasuredHeight())) {
                    //Reaches to the bottom so it is time to updateRecyclerView!
                    updateRecyclerView();
                }
            }
        });
    }

}`

答案 2 :(得分:0)

我为同一个问题苦苦挣扎了好几个小时,看来您需要在回收者视图上添加globallayoutlistener并将代码放入回调中。