Open slmlt opened 4 years ago
Here is the temporary solution to the problem:
class CustomStickyHeaderLinearLayoutManager @JvmOverloads constructor(
context: Context,
orientation: Int = RecyclerView.VERTICAL,
reverseLayout: Boolean = false
) : LinearLayoutManager(context, orientation, reverseLayout) {
override fun findLastVisibleItemPosition(): Int {
return restoreView {
super.findLastVisibleItemPosition()
}
}
override fun findFirstVisibleItemPosition(): Int {
return restoreView {
super.findFirstVisibleItemPosition()
}
}
override fun findFirstCompletelyVisibleItemPosition(): Int {
return restoreView {
super.findFirstCompletelyVisibleItemPosition()
}
}
override fun findLastCompletelyVisibleItemPosition(): Int {
return restoreView {
super.findLastCompletelyVisibleItemPosition()
}
}
/* other methods from copied class */
}
@dmytroivanovv Thanks, I have completely missed the restoreView
method. Reattaching a view is kinda hacky though :)
When findLastCompletelyVisibleItemPosition() is called on StickyHeaderLinearLayoutManager it always returns the position of current sticky header view if one is visible. This behavior breaks any logic built around detecting last displayed items, most common example being list pagination.
The root of the problem seems to be in:
stickyHeader is added to LM without providing index, in which case LM uses mChildHelper.getChildCount(). Later, when LM is cycling through children in reverse order to find last visible item, sticky header view comes up first since its index is getChildCount(). Providing a 0 index to addView() probably is not an option becauses it will break findFirstCompletelyVisibleItemPosition().
It seems that adding an override of findLastCompletelyVisibleItemPosition() to StickyHeaderLinearLayoutManager is needed to fix its behavior.