You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MainActivity更新ViewModel数据,Fragment无法观测到变化求助

问题:MainActivity更新ViewModel后Fragment无法观测到新数据

在MainActivity中尝试更新ViewModel的LiveData数据,但Fragment始终只能观测到ViewModel初始化的默认值"NO DATA YET"。试过两种更新方式:调用ViewModel的update()方法、直接给uzTelNotification.value赋值,均无效。


相关代码

MainActivity 代码(注意存在重复的onCreate方法,应为粘贴失误)

override fun onCreate(savedInstanceState: Bundle?) {
   ...
   uzTelNotifViewModel = ViewModelProvider(this)[UzTelNotifViewModel::class.java]
   binding.uzTelNotifViewModel = uzTelNotifViewModel
   ...
}

// 重复的onCreate,应为同一方法内的代码
override fun onCreate(savedInstanceState: Bundle?) {
  ...
  uzTelNotifViewModel.update("NEW DATA HERE")
  ...
}

UzTelNotifFragment 代码

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    binding.lifecycleOwner = viewLifecycleOwner
    useMaterialSharedAxisXForwardAnimation = false

    viewModel = ViewModelProvider(this)[UzTelNotifViewModel::class.java]
    binding.viewModel = viewModel

    viewModel.uzTelNotification.observe(viewLifecycleOwner) {
        binding.uzTelNotifBar.text = it.toString()
    }
}

UzTelNotifViewModel 代码

class UzTelNotifViewModel : ViewModel() {
    val uzTelNotification = MutableLiveData<String>("NO DATA YET")
    val uzTelNotifVisible = MutableLiveData<Boolean>(true)

    fun update(data: String) {
        uzTelNotification.value = data
    }
}

uz_tel_notif_fragment.xml 代码

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>
        <import type="android.view.View"/>
        <variable
            name="viewModel"
            type="org.linphone.activities.main.viewmodels.UzTelNotifViewModel" />
    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/uztelnotif_fragment_size"
        android:background="?attr/accentColor"
        android:orientation="horizontal"
        android:visibility="@{viewModel.uzTelNotifVisible ? View.VISIBLE : View.GONE, default=gone}"
        >

        <TextView
            android:id="@+id/uzTelNotifBar"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_centerVertical="true"
            android:gravity="center_vertical"
            android:paddingLeft="15dp"
            android:text="@{viewModel.uzTelNotification, default='none'}"
            android:textColor="?attr/accentTextColor"
            android:textSize="15sp" />

    </RelativeLayout>
</layout>

解决方法

核心原因

MainActivity和Fragment各自通过ViewModelProvider(this)创建了独立的ViewModel实例,Activity更新的是自己的ViewModel数据,Fragment观测的是另一个完全独立的ViewModel,所以看不到新数据。

修复步骤

  1. 修正Fragment的ViewModel初始化:
    把Fragment中创建ViewModel的代码,从ViewModelProvider(this)改为ViewModelProvider(requireActivity()),这样Fragment会获取与Activity共享的ViewModel实例:

    // 替换Fragment中的ViewModel初始化代码
    viewModel = ViewModelProvider(requireActivity())[UzTelNotifViewModel::class.java]
    
  2. 修正MainActivity的重复onCreate方法:
    原代码中存在两个重复的onCreate方法,这是粘贴失误,需要合并为一个方法:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ... 其他初始化代码
        uzTelNotifViewModel = ViewModelProvider(this)[UzTelNotifViewModel::class.java]
        binding.uzTelNotifViewModel = uzTelNotifViewModel
        // 在初始化后调用update方法
        uzTelNotifViewModel.update("NEW DATA HERE")
        // ... 其他代码
    }
    
  3. 验证数据绑定(可选):
    确保Fragment的布局绑定中lifecycleOwner已设置为viewLifecycleOwner,你的代码中已经正确设置,无需修改。

额外说明

  • 当需要在Activity和其内部的Fragment之间共享ViewModel时,必须使用Activity作为ViewModel的所有者(即ViewModelProvider(requireActivity()))。
  • 如果是Fragment之间共享ViewModel,也可以使用ViewModelProvider(requireParentFragment())或Activity作为所有者,根据场景选择。

内容的提问来源于stack exchange,提问作者driesken

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 07:37:49