Reputation: 3948
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
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
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