首页 > 解决方案 > 在不使用 LiveData 的情况下从 DialogFragment 调用函数到 Fragment

问题描述

我正在尝试在 aLoginFragment和重置密码对话框片段之间进行通信DialogFragment

DialogFragment某个任务成功时,对话框关闭,我想告诉LoginFragment制作一个小吃店。

我现在这样做的方式是使用 Shared ViewModelbetween LoginFragmentandDialogFragment和 a MutableLiveData

共享视图模型:

class LoginViewModel(private val state: SavedStateHandle) : ViewModel() {
    // used to notify the user when dialog fragment closes with onSuccessListener
    // that the email has been sent using a snackbar
    val snackbarMessageLiveData = MutableLiveData<String>()

    val loginDetailsBundleLiveData = state.getLiveData<Bundle>("login_bundle")
}

对话片段:

task?.let {
    // email sent successfully
    it.addOnSuccessListener {
        // update user that an email has been sent
        viewModel.snackbarMessageLiveData.postValue(getString(R.string.password_recovery_email_sent))
        // closes the fragment
        dialog?.dismiss()
}

登录片段:

viewModel.snackbarMessageLiveData.observe(viewLifecycleOwner, {
    makeSnackbar(it)
})

这是我用来更新 livedata 的行: viewModel.snackbarMessageLiveData.postValue(getString(R.string.password_recovery_email_sent))

但是,这会带来一些错误:

每次我导航到另一个片段,然后导航回LoginFragment观察者loginDetailsBundleLiveData 调用makeSnackbar

我发现了一个丑陋的解决方法......但我希望有一个不使用 livedata 的解决方案

*注:我使用导航组件来调用对话框

val action = fragmentDirections.actionLoginFragmentToDialogPasswordRecoveryFragment()
binding.btnForgotPassword.setOnClickListener {
    findNavController().navigate(action)
}

我想知道是否有更好的方法来做到这一点?也许使用接口?

提前致谢!

标签: androidkotlinandroid-dialogfragment

解决方案


使用此扩展功能,希望对您有所帮助

fun Fragment.setNavigationResult(result: Any?, key: String = 
"result") =findNavController().previousBackStackEntry?.savedStateHandle?.set(key, result)


fun <T> Fragment.getNavigationResult(key: String = "result") =findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<T?>(key)

推荐阅读