What is purpose of overriding containsItem
and getItemId
in FragmentStateAdapter
?
Are these overrides required if one is passing in new lists to the FragmentStatePagerAdapter
implementation and calling notifyDataSetChanged
?
From the doc, appears both overrides are require if the underlying data set is changing, and you need to call notifyDataSetChanged
?
/**
* Default implementation works for collections that don't add, move, remove items.
* <p>
* TODO(b/122670460): add lint rule
* When overriding, also override {@link #getItemId(int)}
*/
public boolean containsItem(long itemId) {
return itemId >= 0 && itemId < getItemCount();
}
/**
* Default implementation works for collections that don't add, move, remove items.
* <p>
* TODO(b/122670460): add lint rule
* When overriding, also override {@link #containsItem(long)}.
* <p>
* If the item is not a part of the collection, return {@link RecyclerView#NO_ID}.
*
* @param position Adapter position
* @return stable item id {@link RecyclerView.Adapter#hasStableIds()}
*/
@Override
public long getItemId(int position) {
return position;
}
So for example, here is my implementation
class MyAdapter(host : Fragment) : FragmentStateAdapter(host) {
data class FragItem(val newInstance : () -> Fragment, val fragId : Long)
private var fragments = mapOf<Integer,FragItem>()
override fun createFragment(position: Int): Fragment {
return fragments[position]?.newInstance?.invoke() ?: DefaultFragment()
}
fun applyDataSet(newFragments : Map<Integer, FragItem>) {
fragments = newFragments
notifyDataSetChanged()
}
override fun getItemCount() = fragments.size
override fun containsItem(itemId: Long): Boolean{
return fragments.any { it.value.fragId == itemId }
}
override fun getItemId(position: Int) : Long{
return fragments.values.elementAt(position).fragId
}
}
Now can I get rid of getItemId
and containsItem
? Or leave them? What about getItemCount
?
getItemCount
will instruct the recycler how many items are to be rendered. the current index will be passed as position
to createFragment
, so clearly you need itgetItemId
and containsItem
implemented if you want to provide stable ID's for your recycler. having stable ID's allows for a certain optimisations to be made, usually when it involves operations on elements that are not next to each-other in the list.