我有一个活动,它在 OnCreate 中为视图模型中的 MutableLiveData 变量实现了一个观察器。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
subscribeDialogFragmentManualInput()
}
private fun subscribeDialogFragmentManualInput() {
this.sharedViewModel.inputBarcode.observe(this) { inputValue ->
postInput(inputValue)
}
}
我的活动始终处于横向模式(清单中默认),当按下按钮时,将打开 DialogFragment 并将旋转更改为纵向,关闭时活动将返回到横向模式。
private fun showInvoiceInputDialog() {
val inputDialog = InvoiceInputDialogFragment
val transaction = supportFragmentManager.beginTransaction()
inputDialog.show(transaction, InvoiceInputDialogFragment.TAG)
}
class InvoiceInputDialogFragment : DialogFragment() {
lateinit var binding: DialogFragmentInvoiceInputBinding
private val sharedViewModel by sharedViewModel<ManualInvoiceInputViewModel>()
private var invoiceInput: String = ""
...
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
setStyle(
STYLE_NORMAL,
R.style.FullScreenDialog
)
binding = DataBindingUtil.inflate(
inflater,
R.layout.dialog_fragment_invoice_input,
container,
false
)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
...
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
setViews()
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
if(invoiceInput.isNotEmpty()) {
sharedViewModel.sendInputInvoice(invoiceInput)
}
}
private fun setViews() {
binding.btConfirmInput.setOnClickListener {
invoiceInput = binding.scannerManualInput.text
dismiss()
}
}
}
此流程使观察者多次触发,使我的应用程序具有和不受欢迎的行为,因为实时数据结果会打开一个对话框并多次显示。
我只想在对话框片段关闭后调用postInput
方法一次。
谢谢!
LiveData
默认设置为近循环逻辑。当视图更新时,这会引发一些问题LiveData
然后LiveData
将想要再次更新视图,从而创建无限循环。尽管您是通过激发Android Lifecycle
重新创建您的Activity
来间接执行此操作的,并且当重新创建时,它会附加另一个观察者,从而重新发出旧值。
您有 2 个选项:
保存对话框已在 savedInstanceState 中调用的事实Bundle
overide fun onSaveInstanceState(savedInstanceState : Bundle?) {
// Save the user's current game state
savedInstanceState.putBoolean("dialogCausedRecreate", dialogWasCreated);
super.onSaveInstanceState(savedInstanceState);
}
//in onCreate
this.sharedViewModel.inputBarcode.observe(this) { inputValue ->
if(!savedInstanceState.getBoolean("dialogCausedRecreate",false)){
postInput(inputValue)
}
}
或
创建一个新的包装类,该包装类可以跟踪是否发出。 这是一个例子 实时数据阻止在开始观察时接收最后一个值
接受的答案将让您将条形码包装在 Event 类中,这将允许您判断它之前是否已经发出。