I've created a bug report for this here in IssueTracker. For me, though, even the notifyItemChanged(position:)
and notifyItemRangeChanged(positionStart:itemCount:)
methods behave incorrectly.
The bug is due to the default implementation of the FragmentStateAdapter.getItemId(position:)
method which simply returns the position
passed into it. The itemId
for each position
will therefore be the same before and after a FragmentStateAdapter.notifyDataSetChanged()
call and therefore none of the Fragment
s will ever be recreated.
One possible workaround is to assign each page a unique id within your FragmentStateAdapter
implementation and to assign a new id to each page whenever the notifyDataSetChanged()
method is called. See the init
block in the ViewPagerAdapter
class below which facilitates this workaround: An AdapterDataObserver
object is registered in this init
block such that it receives a callback whenever notifyDataSetChanged()
is called.
class ViewPagerAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
private var counter = 0L
private var itemIds: List<Long>
init {
itemIds = generateListOfItemIds()
val adapterDataObserver = object : AdapterDataObserver() {
override fun onChanged() {
itemIds = generateListOfItemIds()
}
}
registerAdapterDataObserver(adapterDataObserver)
}
override fun createFragment(position: Int): Fragment {
return PageFragment.newInstance(position)
}
override fun getItemCount(): Int {
return itemIds.size
}
override fun getItemId(position: Int): Long {
return itemIds[position]
}
override fun containsItem(itemId: Long): Boolean {
return itemIds.contains(itemId)
}
private fun generateListOfItemIds() = (1..5).map { counter++ }
}