简体   繁体   中英

RecyclerView findLastCompletelyVisibleItemPosition always returns last element

first question on StackOverflow!

I believe this is due to the fact that the RecyclerView is within a NestedScrollView -- the item is being displayed, however I'd have to scroll down to view it -- but I could definitely be wrong.

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

    //... irrelevant code ... //

   photosRecyclerView = view.findViewById(R.id.profile_recyclerview_photos);
   // Add LayoutManager to RecyclerView.
   GridLayoutManager manager = new GridLayoutManager(getContext(), 2);
   photosRecyclerView.setLayoutManager(manager);
   // Smoothes scrolling from NestedScrollView.
   photosRecyclerView.setNestedScrollingEnabled(false);
   // Add adapter to RecyclerView.
   profileRecyclerViewAdapter = new ProfileRecyclerViewAdapter(getContext(), photoList);
   photosRecyclerView.setAdapter(profileRecyclerViewAdapter);

After some research -- with a lot of help coming from this answer , I realized that this behaviour is due to the fact that the RecyclerView height is set to wrap content. This causes it to load all of the items immediately and thus the last "completely visible" item is the last item in the RecyclerView.

You can try using constraint layout and change the recyclerview height to 0dp .

It will solve your problem

I recently faced an issue with recycler view, tried every possible solution but still failed. So I came up with this lightweight solution.

binding.currencies.apply {
        adapter = currencyPagingAdapter
    }.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)

            val lm = recyclerView.layoutManager as LinearLayoutManager
            val lv = lm.getChildAt(lm.itemCount - 1)

            val scrollBounds = Rect()
            recyclerView.getHitRect(scrollBounds)

            if (lv != null) {
                if (lv.getLocalVisibleRect(scrollBounds)) {
                    Log.d("TAG", "onScrollStateChanged: visible")
                } else {
                    Log.d("TAG", "onScrollStateChanged: not visible")
                }

            }

        }
    })

Had the same problem, I fixed my problem by detecting when nestedScrollView is at the end!

        nestedScrollView.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
        @Override
        public void onScrollChanged() {
            if (nestedScrollView != null) {
                if (nestedScrollView.getChildAt(0).getBottom() <= (nestedScrollView.getHeight() + nestedScrollView.getScrollY())) {
                    //scroll view is at bottom
                    if (isAnythingToLoad && rowsArrayList.size() > 8) {
                            //bottom of list!
                            loadMore();
                    }
                }
            }
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM