Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why findLastCompletelyVisibleItemPosition() is returning -1?

I am trying to do endless recycler view, using pagination in a fragment .
But facing problems as follows.

  1. findLastCompletlyVisibleItemPosition() or findFirstCompletelyVisibleItemPosition() is returning only -1.
  2. if setNestedScrollingEnabled(false), then onScrollStateChanged is not working

Below is a sample of my code. `

        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);
            }
        });
    }

EDIT
The solution of this problem is in the comments section.

like image 304
Saurabh Avatar asked Dec 09 '16 06:12

Saurabh


2 Answers

Look into line no 1732 to 1747 in LinearLayoutManager

/**
 * 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);
}

Here if child is null than you will have NO_POSITION which is -1.

What you are doing:

You are calling below before setting your adapter. There is no View available so you have -1.

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

What you should do:

Your can have findLastVisibleItemPosition and findFirstCompletelyVisibleItemPosition when your adapter's view is completely populate. First set your adapter than get your positions like

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));
like image 112
Haris Qurashi Avatar answered Nov 08 '22 10:11

Haris Qurashi


I struggled with the same issue for hours, It seems you need to add a globallayoutlistener on your recycler view and put your code in the callback.

like image 1
odich daniel Avatar answered Nov 08 '22 11:11

odich daniel