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
相关产品推荐
相关产品推荐

