Tsabary
Tsabary

Reputation: 3948

On scrolled is only called at first load and never again

I am trying to implement infinte scroll but I can't make it to work as I can see by the logs that I've placed that the onScrolled method is only called once when the page first loads and not after, even if I scroll all the way to the bottom. I try going up and down many times but it is never called again.

Could it have anything to do with it being inside a swipeRefreshLayout?

This is my code

Initiating variables

lateinit var lastVisible: DocumentSnapshot
var isScrolling = false
var isLastItemReached = false

Grabbing data from the server function

fun listenToQuestions() {

    questionsRowLayoutAdapter.clear()
    questionsBlockLayoutAdapter.clear()



    db.collection("questions").whereEqualTo("language", currentLanguage)
        .orderBy("last_interaction", Query.Direction.DESCENDING).limit(10)
        .get().addOnSuccessListener {

            for (document in it) {
                val questionObject = document.toObject(Question::class.java)

                           questionsAdapter.add(
                                (SingleBoardBlock(
                                    questionObject,
                                    activity as MainActivity
                                ))
                            )

            }
            Toast.makeText(this.context, "first batch", Toast.LENGTH_SHORT).show()

            questionsAdapter.notifyDataSetChanged()

            lastVisible = it.documents[it.size() - 1]

            val onScrollListener = object : RecyclerView.OnScrollListener() {
                override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                    super.onScrollStateChanged(recyclerView, newState)
                    if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                        isScrolling = true
                        Toast.makeText(activity, "scrolling", Toast.LENGTH_SHORT).show()
                        Log.d("itemsvaues", "new state statement true")
                    } else {
                        Log.d("itemsvaues", "new state statement false")
                    }
                }

                override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                    super.onScrolled(recyclerView, dx, dy)

                    val thisLayoutManager = recyclerView.layoutManager as LinearLayoutManager

                    val firstVisibleItem = thisLayoutManager.findFirstVisibleItemPosition()
                    val visibleItemCount = thisLayoutManager.childCount
                    val totalItemCount = thisLayoutManager.itemCount

                    val countCheck = firstVisibleItem + visibleItemCount == totalItemCount
                    Log.d("itemsvaues", "$firstVisibleItem $visibleItemCount $totalItemCount $countCheck")
                    Log.d("itemsvaues", "is scrolling $isScrolling")
                    Log.d("itemsvaues", "last item reached $isLastItemReached")


                    if (isScrolling && countCheck && !isLastItemReached) {
                        isScrolling = false
                        Log.d("itemsvaues", "if happened")

                        db.collection("questions").whereEqualTo("language", currentLanguage)
                            .orderBy("last_interaction", Query.Direction.DESCENDING).startAfter(lastVisible)
                            .limit(10).get()
                            .addOnSuccessListener { querySnapshot ->

                                for (document in querySnapshot) {
                                    val questionObject = document.toObject(Question::class.java)

                           questionsAdapter.add(
                                (SingleBoardBlock(
                                    questionObject,
                                    activity as MainActivity
                                ))
                            )

                                    }
                                }
                                Toast.makeText(activity, "next batch", Toast.LENGTH_SHORT).show()

                                questionsAdapter.notifyDataSetChanged()

                                lastVisible = querySnapshot.documents[querySnapshot.size() - 1]
                                Log.d("itemsvaues", "next query happened")

                                if (querySnapshot.size() < 10) {
                                    isLastItemReached = true
                                    Toast.makeText(activity, "reached last", Toast.LENGTH_SHORT).show()
                                    Log.d("itemsvaues", "last item reached")

                                }
                            }
                    } else {
                        Log.d("itemsvaues", "if didn't happen")
                    }
                }
            }
            questionsRecycler.addOnScrollListener(onScrollListener)
        }
}

And these are the logs:

2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: 0 10 10 true
2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: is scrolling false
2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: last item reached false
2019-07-20 12:48:49.149 29888-29888/io.poolclub D/itemsvaues: if didn't happen
2019-07-20 12:48:52.181 29888-29888/io.poolclub D/itemsvaues: new state statement true
2019-07-20 12:48:52.328 29888-29888/io.poolclub D/itemsvaues: new state statement false
2019-07-20 12:48:52.530 29888-29888/io.poolclub D/itemsvaues: new state statement false
2019-07-20 12:48:53.481 29888-29888/io.poolclub D/itemsvaues: new state statement true
2019-07-20 12:48:53.645 29888-29888/io.poolclub D/itemsvaues: new state statement false

Upvotes: 2

Views: 1316

Answers (2)

NoHarmDan
NoHarmDan

Reputation: 512

Probably not useful to the original poster anymore, but to other people that come across the same issue:

In my case the problem was that I forgot I have put the RecyclerView inside a NestedScrollView and set it to android:nestedScrollingEnabled="false", which indeed makes the listener fire only once. You can either add the listener to the NestedScrollView then, or see if some of the options discussed in the question below can help you: Recyclerview onscrolllistener not working when setNestedScrollingEnabled to false

Of course there can be other reasons, but this is one of the most easily came across ones.

Upvotes: 3

Javad Shakouri
Javad Shakouri

Reputation: 129

you can try this code

listview.addOnScrollListener(new RecyclerView.OnScrollListener() {

            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);


                visibleItemCount = manager.getChildCount();
                totalItemCount = manager.getItemCount();
                pastVisiblesItems = manager.findFirstVisibleItemPosition();

                if (dy > 0 && pastVisiblesItems >= totalItemCount && !isLoading) {
                    isLoading = true;
                    LoadMoreData();
                }

            }

        });

With this code, you can scroll to the end of the list and load the new information If you need information from item 10 to the end of the list to be loaded

change

if (dy > 0 && pastVisiblesItems >= totalItemCount && !isLoading) {
   isLoading = true;
   LoadMoreData();
}

to

if (dy > 0 && pastVisiblesItems >= totalItemCount - 10 && !isLoading) {
   isLoading = true;
   LoadMoreData();
}

Upvotes: -1

Related Questions