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

Android开发:如何将导航Fragment参数传入ViewModel?

解决方案

一、将Fragment导航参数传入ViewModel

1. 在目标Fragment中获取导航参数

假设接收参数的是UpdateFragment,在该Fragment里用导航组件的navArgs()委托拿到传递的currentStudent:

class UpdateFragment : Fragment() {
    // 通过导航组件自动生成的Args类获取参数
    private val args: UpdateFragmentArgs by navArgs()
    private lateinit var viewModel: MainModleView

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // 初始化ViewModel(后续替换普通ViewModel时会调整这里)
        viewModel = ViewModelProvider(this)[MainModleView::class.java]
        // 把参数传给ViewModel
        viewModel.loadStudentArgs(args.currentStudent)
        // 其他初始化逻辑...
        return binding.root
    }
}

2. 在ViewModel中添加方法更新LiveData

修改你的MainModleView,新增方法接收Student对象并赋值给LiveData:

class MainModleView(application: Application) : AndroidViewModel(application) {
    // 原有代码...

    fun loadStudentArgs(student: Student) {
        inputName.value = student.name
        inputAge.value = student.age.toString() // 若age是Int类型,转成String适配LiveData
    }
}

二、替换AndroidViewModel为普通ViewModel的方案

普通ViewModel没有上下文,所以要通过ViewModel工厂把数据库依赖(Repository/StudentDao)注入进去,不在ViewModel内部创建数据库实例:

1. 编写ViewModel工厂类

class MainViewModelFactory(private val repository: Repository) : ViewModelProvider.Factory {
    override fun <T : ViewModel> create(modelClass: Class<T>): T {
        if (modelClass.isAssignableFrom(MainModleView::class.java)) {
            @Suppress("UNCHECKED_CAST")
            return MainModleView(repository) as T
        }
        throw IllegalArgumentException("未知的ViewModel类")
    }
}

2. 重构为普通ViewModel

移除Application参数,改用构造函数注入Repository:

class MainModleView(private val repository: Repository) : ViewModel() {
    val getAllStudentData: LiveData<List<Student>> = repository.getAllData

    val inputName = MutableLiveData<String>()
    val inputAge = MutableLiveData<String>()

    fun loadStudentArgs(student: Student) {
        inputName.value = student.name
        inputAge.value = student.age.toString()
    }
}

3. 在Fragment中通过工厂初始化ViewModel

class UpdateFragment : Fragment() {
    private val args: UpdateFragmentArgs by navArgs()
    private lateinit var viewModel: MainModleView

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        // 获取Repository实例
        val studentDao = StudentDatabase.getAllData(requireContext()).studentDao()
        val repository = Repository(studentDao)
        // 通过工厂创建ViewModel
        viewModel = ViewModelProvider(this, MainViewModelFactory(repository))[MainModleView::class.java]
        // 传递导航参数
        viewModel.loadStudentArgs(args.currentStudent)
        // 其他初始化逻辑...
        return binding.root
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 15:55:20