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

使用ViewModel和LiveData无法在Fragment间传递数据问题排查

问题原因

你当前的核心问题是两个Fragment各自持有独立的ViewModel实例。在HomeFragment和ListFragment中,你都用ViewModelProvider(this)获取ViewModel,这会让每个Fragment创建专属的ViewModel对象——HomeFragment更新的数据只会存在于自己的ViewModel里,ListFragment的ViewModel还是初始状态,自然始终显示"No Item"。

解决方案

要实现数据共享,需将ViewModel的作用域绑定到两个Fragment所属的Activity上,让它们共用同一个ViewModel实例。只需修改两个Fragment中获取ViewModel的代码,用requireActivity()替代this即可。

修改HomeFragment.kt的ViewModel初始化

将原代码中的ViewModel获取语句替换:

// 原代码
mainViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)

// 修改后
mainViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java)

完整修改后的HomeFragment.kt:

class HomeFragment : Fragment() {

    private lateinit var mainViewModel : MainActivityViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragmentHomeBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)

        // 绑定到Activity作用域,共享ViewModel实例
        mainViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java)
        binding.viewModel = mainViewModel
        binding.lifecycleOwner = this

        binding.tvGroceries.setOnClickListener {
            mainViewModel.updateItemType(0)
            it.findNavController().navigate(R.id.action_homeFragment_to_listFragment)
        }
        binding.tvElectronics.setOnClickListener {
            Log.d("sagar", "clicked ")
            mainViewModel.updateItemType(1)
            it.findNavController().navigate(R.id.action_homeFragment_to_listFragment)
        }

        return binding.root
    }

}

修改ListFragment.kt的ViewModel初始化

同样替换ViewModel获取语句:

// 原代码
mainViewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)

// 修改后
mainViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java)

完整修改后的ListFragment.kt:

class ListFragment : Fragment() {
    private lateinit var mainViewModel : MainActivityViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding : FragmentListBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_list, container, false)

        // 绑定到Activity作用域,共享ViewModel实例
        mainViewModel = ViewModelProvider(requireActivity()).get(MainActivityViewModel::class.java)
        binding.viewModel = mainViewModel
        binding.lifecycleOwner = this
        return binding.root
    }

}
验证逻辑

修改完成后:

  1. 点击HomeFragment的按钮时,更新的是Activity作用域下ViewModel的LiveData值
  2. ListFragment观察的是同一个LiveData对象,数据绑定会自动感知值的变化,更新TextView内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:50:30