【问题标题】:LiveData Consumer in BaseFragment not receiving updates from BaseViewModelBaseFragment 中的 LiveData Consumer 未从 BaseViewModel 接收更新
【发布时间】:2021-03-23 09:11:59
【问题描述】:

我有一个看起来像这样的 BaseFragment.kt

open class BaseFragment: Fragment() {

private lateinit var viewModel: BaseViewModel

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    viewModel = ViewModelProvider(this).get(BaseViewModel::class.java)
    observeNavigationCommands()
}

/**
 * Method that observes Navigation commands triggered by BaseViewHolder
 * This allows us to navigate from a viewHolder using the MVVM pattern
 */
private fun observeNavigationCommands() {
    viewModel.navigationCommands.observe(viewLifecycleOwner, EventObserver {
        Timber.e("received nav command $it")
        when(it) {
            is NavigationCommand.To -> findNavController().navigate(it.destinationId)
            is NavigationCommand.Back -> findNavController().popBackStack()
            is NavigationCommand.BackTo -> TODO()
            NavigationCommand.ToRoot -> TODO()
        }
    })
}

}

...还有一个看起来像这样的 BaseViewModel.kt

open class BaseViewModel: ViewModel() {

val navigationCommands = MutableLiveData<Event<NavigationCommand>>()

/**
 * Navigate to a specific fragment using Id
 */
fun navigate(id: Int) {
    Timber.e("trigger navigation event $id")
    // navigationCommands.postValue(NavigationCommand.To(id))
    navigationCommands.value = Event(NavigationCommand.To(id))
}

/**
 * Pop backStack
 */
fun goBack() {
    navigationCommands.value = Event(NavigationCommand.Back)
}

}

NavigationCommand 类看起来像

sealed class NavigationCommand {

data class To(val destinationId: Int) : NavigationCommand()
data class BackTo(val destinationId: Int): NavigationCommand()

object Back: NavigationCommand()
object ToRoot: NavigationCommand()

}

现在在我的其他扩展 BaseViewModel 的视图模型中,我希望能够调用 navigate(R.id.action_fragmentA_to_fragmentB) 但问题是 observeNavigationCommands() 中的消费者永远不会收到 NavigationCommands

.....

但如果我复制observeNavigationCommands() 的内容并将其放在我当前的片段(扩展BaseFragment 的片段)中,消费者会收到更新

我错过了什么?请帮忙

【问题讨论】:

    标签: android kotlin mvvm android-livedata


    【解决方案1】:

    我是否理解正确,对于扩展 BaseFragment 的片段,您想要附加扩展 BaseViewModel 的 viewModel,但这不适用于 liveData?

    如果是这样,请查看我创建的这个简单的工作项目以反映您的情况:

    https://github.com/phamtdat/OpenViewModelDemo

    重点是使viewModel 可覆盖并在扩展BaseFragment 的片段中覆盖它。

    【讨论】:

    • 感谢您的解决方案,但我想要的是能够从 ViewModel 调用导航方法,而不是片段...我将您的代码修改为该效果并遇到同样的问题目前有请修改您的空 MyViewModel 类以具有包装方法,例如:fun mNav() { naviagte(123456) } 并通过从您的片段中调用 mNav() 而不是 navigate(123456) 进行测试,我确定您;我会看到我在说什么
    • 嗯,无法重现您所描述的内容。我看到了事件被触发的日志。也许我没有使用的 Event 类存在问题,它的 build.gradle 依赖项是什么?我没有使用它,因为我不知道依赖关系。如果您有重现问题的修改代码,请向存储库发出拉取请求,我会看看。无论如何都要检查它,因为我使用包装的函数进行了更新。
    • 顺便说一句,为什么要使用包装函数而不是让navigate 变得有趣并在MyViewModel 中覆盖它?在那里你做你自己的逻辑,然后调用super.navigate(...),然后在片段中你不需要做任何类转换
    • 谢谢...您的解决方案有效,但我创建了一个对 repo 的拉取请求,其中包含一些试图描述我的场景的更改...请看一下...
    • 好的,我终于明白你的问题了。查看存储库的新更新,看看是否能回答您的问题。从 MySampleFragment 开始
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-12
    • 2020-10-25
    相关资源
    最近更新 更多