覆盖 `FragmentStateAdapter` 中的 `containsItem` 和 `getItemId` 的目的是什么?
What is purpose of overriding `containsItem` and `getItemId` in `FragmentStateAdapter`?
在 FragmentStateAdapter
中覆盖 containsItem
和 getItemId
的目的是什么?
如果将新列表传递给 FragmentStatePagerAdapter
实现并调用 notifyDataSetChanged
,是否需要这些覆盖?
从文档中可以看出,如果基础数据集正在更改,那么这两个覆盖都是必需的,并且您需要调用 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;
}
例如,这是我的实现
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
}
}
现在我可以删除 getItemId
和 containsItem
吗?还是离开他们? getItemCount
呢?
getItemCount
将指示回收商要渲染多少项目。当前索引将作为 position
传递给 createFragment
,因此显然您需要它
- 如果您想为回收商提供稳定的 ID,则实施
getItemId
和 containsItem
。具有稳定的 ID 允许进行某些优化,通常是当它涉及对列表中不相邻的元素进行操作时。
在 FragmentStateAdapter
中覆盖 containsItem
和 getItemId
的目的是什么?
如果将新列表传递给 FragmentStatePagerAdapter
实现并调用 notifyDataSetChanged
,是否需要这些覆盖?
从文档中可以看出,如果基础数据集正在更改,那么这两个覆盖都是必需的,并且您需要调用 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;
}
例如,这是我的实现
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
}
}
现在我可以删除 getItemId
和 containsItem
吗?还是离开他们? getItemCount
呢?
getItemCount
将指示回收商要渲染多少项目。当前索引将作为position
传递给createFragment
,因此显然您需要它- 如果您想为回收商提供稳定的 ID,则实施
getItemId
和containsItem
。具有稳定的 ID 允许进行某些优化,通常是当它涉及对列表中不相邻的元素进行操作时。