Android:从ViewModel作为回调调用时,getActivity为null

问题描述

我用DataBinding设置了我的项目,因此单击了RecyclerView Item,Fragment的viewmodel获取了数据,需要更改Fragment。因此,我创建了一个回调,该回调在Fragment本身中进行了更改,但是在调用它时,getActivity()函数(或如下所示的“ activity?”函数)为null。

回调界面

interface FragmentCallBack {
    fun fragmentCallBack(object: Object?)
}

片段

class MainFragment : Fragment(),FragmentCallBack {
    override fun fragmentCallBack(object: Object?) {
        val fragment = NewFragment.newInstance()
        // Here is the issue <------------------------
        activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.container,fragment)?.commit()
    }
}

片段viewmodel

class Fragmentviewmodel : viewmodel() {
    val callback: FragmentCallBack = MainFragment()

    private fun getData(string: String) {
        val liveData = Repository.getData(string)
        callback.fragmentCallBack(liveData.value)
    }
}

解决方法

您在ViewModel中手动构造MainFragment,而没有将其正确添加到任何容器中。在这种情况下,它与任何活动都不相关,因此NPE是预期的结果。

此代码存在几个问题:

  • 片段应添加到容器中。最好的方法是使用一些片段管理库
  • ViewModel不应“了解”有关片段的任何信息
  • 从外部(例如fragmentCallback)对片段调用方法总是解决问题的方法
  • [最佳实践]如果您有一个名为getData的方法,则调用导致导航的回调可能不是最佳设计。这不是名字所暗示的,命名很重要。

坦率地说,这段代码表明您对Fragments和ViewModels不太了解,因此建议您仔细阅读本文档。否则,使用这两个复杂的API可能会导致很多问题和沮丧。