【问题标题】:Unable to observe livedata set in viewmodel from activity无法从活动中观察视图模型中的实时数据集
【发布时间】:2021-02-26 01:08:29
【问题描述】:

我是一名新手 Android 开发人员,我正在尝试从其父项的活动中观察 ViewModel 中的布尔集。我可以在应用程序启动后立即观察其初始状态,但以后应用的任何更改似乎都不会触发观察者(即当我切换片段时)。

这是我的 ViewModel 的代码:

class MyMusicViewModel  : ViewModel() {


    private var _MyMusicViewOn = MutableLiveData<Boolean>()
    val MyMusicViewOn: LiveData<Boolean> get() = _MyMusicViewOn



    init {
        Timber.i("MyMusicViewModel Init Called!")
        setMyMusicView(true)
    }

    override fun onCleared() {
        super.onCleared()
        Timber.i("MyMusicViewModel Cleared!")
        setMyMusicView(false)
    }


    fun setMyMusicView(setter: Boolean) {
        Timber.i("MyMusicViewModel setter called! %s", setter)
        _MyMusicViewOn.value = setter
    }


}

这是它父母的活动:

class FullscreenActivity : AppCompatActivity() {


    private val viewModel: MyMusicViewModel by viewModels()

  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

       
        viewModel.MyMusicViewOn.observe(this, Observer { MyMusicViewOn ->
            Timber.i("Observer called for MyMusicViewOn %s", MyMusicViewOn)
        })

    }

}

如果你想查看 ViewModel 的相关片段,这里是:

class MyMusicFragment : Fragment() {

    private lateinit var viewModel: MyMusicViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val binding = DataBindingUtil.inflate<FragmentMyMusicBinding>(
            inflater,
            R.layout.fragment_my_music,
            container,
            false
        )
        
        viewModel = ViewModelProvider(this).get(MyMusicViewModel::class.java)

        return binding.root
    }
    

    override fun onResume() {
        super.onResume()

        Timber.i("MyMusicViewFragment resumed!")
        viewModel.setMyMusicView(true)

    }




}

我想要完成的是观察 onResume()、onCleared() 和 init{} 函数,只要通过更改 MyMusicViewOn MutableLiveData 布尔值的状态来调用它们。我不明白的是,为什么该布尔值在更改时不会触发父活动中的观察者集。

提前感谢您的任何想法!

一切顺利,

工厂。

【问题讨论】:

  • 您的MyMusicFragment 中有一个lateinit var viewModel: MyMusicViewModel,但您没有包含任何设置该viewModel 对象的代码。你能包括那个代码吗?
  • 你说得对,对不起,我忘了包含那个代码。我已经编辑了我上面的帖子。谢谢!

标签: android kotlin mutablelivedata


【解决方案1】:

我猜无论您在 Fragment 中填充 viewModel 属性,您都没有使用 Activity 的 ViewModel 实例。获取 Activity 使用的相同实例的最简单方法是使用 activityViewModels 委托:

private val viewModel: MyMusicViewModel by activityViewModels()

【讨论】:

  • 感谢您的回答。好的,我想该行必须放在 Fragment 中,以代替“private lateinit var viewModel: MyMusicViewModel”。我对么?我这样做了,但是后来我遇到了“viewModel = ViewModelProvider(this).get(MyMusicViewModel::class.java)”的错误,所以我删除了该行并且没有给出错误,我可以运行应用程序,现在我看到每次正确观察到的变量 MyMusicViewOn 都设置为“true”,但是......永远不会设置为“false”。有什么想法吗?
  • 您在onCleared() 中将其设置为false,这意味着活动处于非活动状态,因为Livedata 具有生命周期意识,它不会发布这些更改。
  • 是的,没错。正如@rajan.kali 所说,onCleared 在与观察者的活动已经分离后被调用,因此没有更多的观察者将更改记录为 false。
  • 谢谢你们!现在一切都清楚了,这是有道理的。我有一个计划来处理这一切。再次非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-05
  • 2020-08-14
  • 2013-11-14
  • 1970-01-01
  • 2018-05-13
  • 2014-03-12
  • 2017-02-19
相关资源
最近更新 更多