如何在Firestore分页适配器中通过模型项id值获取对应条目位置
Firestore 分页适配器条目获取与位置定位实现
Firestore Paging Adapter 基于 Android Paging 组件实现分页加载,和普通直接持有全量数据集的列表适配器逻辑存在差异,两个核心需求的落地逻辑如下:
一、获取指定位置的模型类条目
Firestore Paging Adapter 没有直接暴露可遍历全量数据集的公开入口,需根据适配的Paging版本选择对应获取方式:
- 适配Paging 2的旧版
FirestorePagingAdapter:直接调用适配器自带的getItem(int position)方法,可获取对应位置的快照对象,通过快照解析映射得到目标模型类实例,使用前需做非空判断——分页加载未覆盖的位置可能不存在有效数据。 - 适配Paging 3的新版Firestore分页适配器:依托
PagingDataAdapter的peek(int position)方法,在内存已加载对应位置数据的前提下,可直接拿到映射好的模型类条目,同样需要做非空判空处理。
二、通过模型属性值定位条目所在位置
普通列表适配器靠全量遍历数据集比对id的逻辑,无法直接套用到分页适配器场景:分页组件的数据集是懒加载的,未加载页的内容不会存到内存中,强行全范围遍历不仅会取到大量空值,还会带来不必要的性能开销。
可根据使用的Paging版本选择对应实现:
- Paging 2场景:
Paging 2会把已加载分页页的内容全量保存在内存的PagedList对象中,可拿到适配器持有的当前PagedList引用,只遍历已加载的有效范围做比对,参考实现代码:private int getAdapterItemPosition(long targetId) { PagedList<QuerySnapshot> loadedList = mFirestorePagingAdapter.getCurrentList(); for (int position = 0; position < loadedList.size(); position++) { QuerySnapshot snapshot = loadedList.get(position); if (snapshot == null) continue; YourModel currentModel = snapshot.toObject(YourModel.class); if (currentModel != null && currentModel.getId() == targetId) { return position; } } // 找不到时返回NO_POSITION而非0,避免误操作列表首个条目 return RecyclerView.NO_POSITION; } - Paging 3场景:
Paging 3采用带缓存窗口的懒加载机制,没有连续存在内存的全量已加载数据集,更合理的实现是在ViewModel层维护Map<Long, Integer>的id与位置映射缓存:在收集PagingData流的过程中,遍历已加载的条目同步更新映射关系,定位时直接从Map中取值,无需临时遍历比对。
注意:普通适配器代码中找不到对应id时返回0的逻辑存在隐患,0是列表第一个条目的有效位置,实际开发中找不到条目时返回
RecyclerView.NO_POSITION(值为-1),避免后续条目点击、内容更新等逻辑误操作首个条目。
内容的提问来源于stack exchange,提问作者Beginner Dev
相关产品推荐
相关产品推荐

