I have RecyclerView inside NestedScrollView
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
I have this problem in big project and in order to find solution for this problem I have created new project without other views.
This is full code of MainActivity
class MainActivity : AppCompatActivity() {
var mItems = mutableListOf<String>()
var mAdapter = MyAdapter(mItems)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recycler.layoutManager = LinearLayoutManager(this)
recycler.adapter = mAdapter
delayedLoadDataIfPossible(100)
recycler.viewTreeObserver.addOnScrollChangedListener {
delayedLoadDataIfPossible(100)
}
}
private fun delayedLoadDataIfPossible(delay: Long) {
Observable.timer(delay, TimeUnit.MILLISECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
var scrollingReachedEnd = isScrollingReachedEnd()
if (scrollingReachedEnd) {
loadData()
}
}
}
private fun isScrollingReachedEnd(): Boolean {
val layoutManager = LinearLayoutManager::class.java.cast(recycler.layoutManager)
val totalItemCount = layoutManager.itemCount
val lastVisible = layoutManager.findLastVisibleItemPosition()
return lastVisible + 5 >= totalItemCount
}
private fun loadData() {
Observable.timer(5, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.doOnSubscribe { progress.visibility = View.VISIBLE }
.doFinally { progress.visibility = View.GONE }
.subscribe {
for (i in 1..10) {
mItems.add(i.toString())
}
mAdapter.notifyDataSetChanged()
delayedLoadDataIfPossible(100)
}
}
}
I am using isScrollingReachedEnd method to identify is scrolling reaching end of list. If there are less than 5 visible items in the end, I am trying to load new data.
loadData simulates loading data. It adds 10 items to list and notifies adapter about change.
delayedLoadDataIfPossible method should work after some delay because findLastVisibleItemPosition is returning value before items are added to list. In result it is returning wrong value. For example -1 after adding first 10 items.
My problem: when RecyclerView inside NestedScrollView findLastVisibleItemPosition returning wrong value and data loading can not be stopped even there are enough items. There is no such problem when RecyclerView not inside NestedScrollView.
My question: how to get last visible item position from RecyclerView when it is inside NestedScrollView?