android - Android分页3:可以从PagingData获取itemcount?
问题描述
我如何才能获得我PagingData<Product>
持有的当前数量的物品?我找到的唯一解决方案是调用shopListAdapter.itemCount
,但这总是返回 0。
我要做的是:获取我的 PagingAdapter 当前显示的当前项目数量,将此值提交给我的 shopViewModel,然后在另一个片段(DialogFragment)中使用此值。或者:从我的视图模型中获取项目的PagingData<Product>
数量
这是我目前的方法
主要片段
@AndroidEntryPoint
class ShopFragment : Fragment(R.layout.fragment_shop), ShopAdapter.OnItemClickListener {
private val shopViewModel: ShopViewModel by navGraphViewModels(R.id.nav_shop) { defaultViewModelProviderFactory }
private var _shopBinding: FragmentShopBinding? = null
private val shopBinding: FragmentShopBinding get() = _shopBinding!!
@Inject lateinit var shopListAdapter: ShopAdapter
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_shopBinding = FragmentShopBinding.inflate(inflater, container, false)
return shopBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
collectShopList()
}
private fun collectShopList(){
shopViewModel.shopPagingData.observe(viewLifecycleOwner) {
shopListAdapter.submitData(viewLifecycleOwner.lifecycle, it)
shopViewModel.setItemAmount(shopListAdapter.itemCount)
}
}
}
对话片段
@AndroidEntryPoint
class ShopFilterFragment : DialogFragment() {
private val shopViewModel: ShopViewModel by navGraphViewModels(R.id.nav_shop) { defaultViewModelProviderFactory }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_shop_filter, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
shopViewModel.itemAmount.observe(viewLifecycleOwner) {
toast(it.toString()) <-- Always displays 0
}
}
}
视图模型
class ShopViewModel @ViewModelInject constructor(
private val shopRepository: ShopRepository
) : ViewModel() {
private val _itemAmount = MutableLiveData<Int>()
val itemAmount: LiveData<Int> get() = _itemAmount
private val query = MutableLiveData(QueryHolder(null, null, null))
val shopPagingData = query.switchMap { query -> shopRepository.search(query).cachedIn(viewModelScope) }
fun search(newQuery: QueryHolder) {
query.value = newQuery
}
fun setItemAmount(amount: Int) {
_itemAmount.value = amount
}
}
解决方案
adapter.itemCount
是正确的方法,但请注意,它有可能与适配器收到的内容竞争(页面将加载然后通知适配器 - 如果您.itemCount
在这些步骤之间调用,它将返回不正确的数字)。
要等待适配器呈现页面,最简单的方法是使用loadStateListener
/ loadStateFlow
,因为LoadState
更新保证与适配器事件同步。
shopListAdapter.addLoadStateListener { combinedLoadStates ->
// If you don't want to call all the time, you
// can filter on changes in combinedLoadStates
shopViewModel.setItemAmount(shopListAdapter.itemCount)
}
不要忘记取消注册以防泄漏。
或者,您可以使用基于流的方法:
.. onViewCreated(..) {
viewLifecycleOwner.lifecycleScope.launch {
shopListAdapter.loadStateFlow.collect { combinedLoadStates ->
// If you don't want to call all the time, you
// can filter on changes in combinedLoadStates
shopViewModel.setItemAmount(shopListAdapter.itemCount)
}
}
}
推荐阅读
- javascript - 对于质量选择,视频 js 齿轮图标不可见
- python - “API”弥合 Python 和 ODBC 数据源之间的 Linux/Windows-KVM 差距
- python-3.x - Mac OS Big Sur 上的高内存使用率
- google-cloud-platform - Google Cloud Authentication - 获取我的应用程序的密钥 ID
- c# - 合并 TCP C# 发送的块
- reactjs - React 应用部署到 Heroku-css/scss 问题
- c# - TcpClient Read() IOException 错误代码 10060
- javascript - TypeError:无法读取 null 的属性“地址”
- c# - 带有双列表框的 ASP.NET Core
- c# - Aspnet 核心 json 序列化 - camelCase 命名策略应该只在第一个字符上改变大小写