启动新片段时重新加载片段后触发 LiveData 观察器,但 AlertDialog 不会
我在 LiveBarcodeScanningFragment 上有一个 LiveData 观察器,用于观察条形码实时数据,之后如果检测到,BarcodeBottomSheetFragment 将启动(扩展 Fragment 而不是具有更多动画的 BottomSheetDialogFragment)。
但这是问题,LiveBarcodeScanningFragment 上的观察者在加载片段后立即触发(已实现 SingleLiveEvent 扩展 Google 中的 MutableLiveData)。
我已经测试AlertDialog可以实现我的目标。 在调试模式下,我看到,当我使用AlertDialog时,它会完成观察,然后打开AlertDialog。当我关闭对话框时,它不会重新触发观察。
这是我的代码
wm= ViewModelProvider(this@LiveBarcodeScanningFragment).get(WorkflowModel::class.java)
wm.searchedProduct.observe(viewLifecycleOwner) { searchedRes ->
// THIS fragment = (LiveBarcodeScanningFragment)
// extend fragment instead of BottomSheetDialogFragment,
// it will open new fragment directly, block the observation,
// and occur the problem, when I return to THIS fragment(LiveBarcodeScanningFragment),
// it will run here again and again. (been observed to get changed )
// BG: BarcodeBottomSheetFragment replace THIS fragment.
/*
* private fun openFragment(
* fm: FragmentManager,
* frag: BarcodeBottomSheetFragment, fragTag: String
* ) {
* fm.beginTransaction()
* .replace(
* R.id.activity_live_barcode_container,
* frag
* )
* .addToBackStack(fragTag)
* .commit()
* }
* */
BarcodeBottomSheetFragment.openAddBarcodeToDatabaseAndCartPage(
parentFragmentManager,
getDeviceInfo(),
null,
wm.adapter!!,
searchedRes
)
// use Debug, I saw, it will finish observation, then open AlertDialog.
// will not re-trigger observation
AlertDialog.Builder(requireContext())
.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(
android.R.string.yes
) { dialog, which -> }
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
Timber.d("AlertDialog END... ")
}
// will not re-trigger observation
更新:
这是我的临时解决方案,使用添加而不是像 DialogFragment.show 方法那样替换。
fm.beginTransaction()
.add(R.id.activity_live_barcode_container, frag)
.addToBackStack(fragTag).commit()
I have a LiveData observer on LiveBarcodeScanningFragment that observes barcode live data, after which if detected, BarcodeBottomSheetFragment will start (extend Fragment instead of BottomSheetDialogFragment which have more animations).
But here's the problem, the observer on LiveBarcodeScanningFragment triggered immediately after loading the fragment (Have implement SingleLiveEvent extend MutableLiveData in Google).
I have test AlertDialog can achieve my goal.
In Debug mode, I saw that, when I use AlertDialog, it will finish observation, then open AlertDialog. When I dismiss the dialog, It will not retrigger the observation.
Here are my codes
wm= ViewModelProvider(this@LiveBarcodeScanningFragment).get(WorkflowModel::class.java)
wm.searchedProduct.observe(viewLifecycleOwner) { searchedRes ->
// THIS fragment = (LiveBarcodeScanningFragment)
// extend fragment instead of BottomSheetDialogFragment,
// it will open new fragment directly, block the observation,
// and occur the problem, when I return to THIS fragment(LiveBarcodeScanningFragment),
// it will run here again and again. (been observed to get changed )
// BG: BarcodeBottomSheetFragment replace THIS fragment.
/*
* private fun openFragment(
* fm: FragmentManager,
* frag: BarcodeBottomSheetFragment, fragTag: String
* ) {
* fm.beginTransaction()
* .replace(
* R.id.activity_live_barcode_container,
* frag
* )
* .addToBackStack(fragTag)
* .commit()
* }
* */
BarcodeBottomSheetFragment.openAddBarcodeToDatabaseAndCartPage(
parentFragmentManager,
getDeviceInfo(),
null,
wm.adapter!!,
searchedRes
)
// use Debug, I saw, it will finish observation, then open AlertDialog.
// will not re-trigger observation
AlertDialog.Builder(requireContext())
.setTitle("Delete entry")
.setMessage("Are you sure you want to delete this entry?")
.setPositiveButton(
android.R.string.yes
) { dialog, which -> }
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show()
Timber.d("AlertDialog END... ")
}
// will not re-trigger observation
update:
Here is my temporary solution, use add rather than replace like DialogFragment.show method do.
fm.beginTransaction()
.add(R.id.activity_live_barcode_container, frag)
.addToBackStack(fragTag).commit()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

这是设计使然。 LiveData 仅在数据发生变化时提供更新,而且仅向活跃观察者提供更新。在这种情况下,活动是指应用程序组件的生命周期状态。因此,例如,如果您在片段的 onResume 函数中注册了观察者,它将在恢复时收到更新,从而触发您的 AlertDialog。
您没有与观察者调用共享代码,但您需要确保将其移至
onCreate
(如果尚未移至此处)。 观察 LiveData 对象 中的这一部分对此进行了最好的解释。This is by design. LiveData delivers updates only when data changes, but also only to active observers. In this context, active refers to the lifecycle state of the app component. So, for example, if you have your observer registered in the
onResume
function of your fragment, it will receive an update when it resumes, triggering your AlertDialog.You didn't share code with your observer call, but you'll want to make sure you move it to
onCreate
if not there already. This section in Observe LiveData objects explains it the best.