Recyclerview 在片段中使用 LiveData onBackPressed 重复值
Recyclerview Duplicate Values with LiveData onBackPressed in Fragment
我有一个加载更多的 recyclerview,我无法将值存储在数据库中。因此,当我加载数据时,一切正常。当我导航到另一个片段并单击 onBackPressed 时,问题发生了,再次调用了观察者的 onChanged,它为我提供了从 API 调用的最后一个值。然后正如您在下面的代码中看到的那样,它们会自动添加到列表中并在 UI
中发布
productsViewModel.productsObject.observe(viewLifecycleOwner, Observer { result ->
if (result.status != Status.LOADING) {
(activity as MainActivity?)!!.dismissProgressDialog(getView())
if (result.status == Status.SUCCESS && result.data != null) {
val productsResult = parseObject(result.data.asJsonObject)
if (!productsResult.isNullOrEmpty()) {
products.addAll(productsResult)
productAdapter.submitList(products)
progressBar.visibility = View.GONE
numberSearch.text = products.size.toString() + "/" + total + " " + resources.getString(R.string.items_found)
} else if (result.status == Status.ERROR) {
if (result.message.isNullOrBlank())
Utils.showSnackBar(requireContext(), view, getString(R.string.something_wrong_try_again), true)
else
Utils.showSnackBar(requireContext(), view, result.message, true)
}
}
}
})
我认为你没有正确观察你的 result
。
例如,如果 result
的值为 Status.LOADING
会发生什么?在你进入那个街区之后,也许还有其他的情况你没有处理。我们不知道,因为没有其他 when
或 else if
块。
另一种方式 "clean" 是:
productsViewModel.productsObject.observe(viewLifecycleOwner, Observer { result ->
when(result.status) {
Status.LOADING -> manageLoading()
Status.SUCCESS -> manageSuccess()
Status.ERROR -> manageError()
else -> manageBaseCase()
}
}
因此,它并没有全部嵌入到一个独特的 if
块中,从而使管理更容易理解。
在您的 Fragment 中,您应该手动发送一个事件到 "reset" LiveData 的实际状态,这样您就可以确保不会有重复项。
您的片段可能看起来像这样:
class ProductsFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.product_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
observe()
productsViewModel.send(Event.Load)
}
}
我有一个加载更多的 recyclerview,我无法将值存储在数据库中。因此,当我加载数据时,一切正常。当我导航到另一个片段并单击 onBackPressed 时,问题发生了,再次调用了观察者的 onChanged,它为我提供了从 API 调用的最后一个值。然后正如您在下面的代码中看到的那样,它们会自动添加到列表中并在 UI
中发布 productsViewModel.productsObject.observe(viewLifecycleOwner, Observer { result ->
if (result.status != Status.LOADING) {
(activity as MainActivity?)!!.dismissProgressDialog(getView())
if (result.status == Status.SUCCESS && result.data != null) {
val productsResult = parseObject(result.data.asJsonObject)
if (!productsResult.isNullOrEmpty()) {
products.addAll(productsResult)
productAdapter.submitList(products)
progressBar.visibility = View.GONE
numberSearch.text = products.size.toString() + "/" + total + " " + resources.getString(R.string.items_found)
} else if (result.status == Status.ERROR) {
if (result.message.isNullOrBlank())
Utils.showSnackBar(requireContext(), view, getString(R.string.something_wrong_try_again), true)
else
Utils.showSnackBar(requireContext(), view, result.message, true)
}
}
}
})
我认为你没有正确观察你的 result
。
例如,如果 result
的值为 Status.LOADING
会发生什么?在你进入那个街区之后,也许还有其他的情况你没有处理。我们不知道,因为没有其他 when
或 else if
块。
另一种方式 "clean" 是:
productsViewModel.productsObject.observe(viewLifecycleOwner, Observer { result ->
when(result.status) {
Status.LOADING -> manageLoading()
Status.SUCCESS -> manageSuccess()
Status.ERROR -> manageError()
else -> manageBaseCase()
}
}
因此,它并没有全部嵌入到一个独特的 if
块中,从而使管理更容易理解。
在您的 Fragment 中,您应该手动发送一个事件到 "reset" LiveData 的实际状态,这样您就可以确保不会有重复项。
您的片段可能看起来像这样:
class ProductsFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.product_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
observe()
productsViewModel.send(Event.Load)
}
}