【发布时间】:2021-04-23 21:00:00
【问题描述】:
我有一个包含一个活动和两个片段的应用程序,在第一个片段中,我应该能够将数据插入数据库,在第二个片段中,我应该能够在 recyclerView 中看到添加的项目。
所以我已经制作了数据库、我的 RecyclerView 适配器和 ViewModel,
现在的问题是我应该如何管理这一切?
我是否应该在 Activity 中初始化 ViewModel 并从片段中以某种方式调用它以使用插入?
我应该在两个片段中初始化视图模型两次吗?
我的代码如下所示:
假设我在我的 Activity 中初始化了 viewholder:
class MainActivity : AppCompatActivity() {
private val articoliViewModel: ArticoliViewModel by viewModels {
ArticoliViewModelFactory((application as ArticoliApplication).repository)
}
}
然后我应该使用 viewModel 将数据添加到数据库的 FirstFragments 方法如下所示:
class FirstFragment : Fragment() {
private val articoliViewModel: ArticoliViewModel by activityViewModels()
private fun addArticolo(barcode: String, qta: Int) { // function which add should add items on click
// here i should be able to do something like this
articoliViewModel.insert(Articolo(barcode, qta))
}
}
还有我的第二个片段
class SecondFragment : Fragment() {
private lateinit var recyclerView: RecyclerView
private val articoliViewModel: ArticoliViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
recyclerView = view.findViewById(R.id.recyclerView)
val adapter = ArticoliListAdapter()
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(activity)
// HERE I SHOULD BE ABLE DO THIS
articoliViewModel.allWords.observe(viewLifecycleOwner) { articolo->
articolo.let { adapter.submitList(it) }
}
}
}
编辑:
我的 ViewModel 如下所示:
class ArticoliViewModel(private val repository: ArticoliRepository): ViewModel() {
val articoli: LiveData<List<Articolo>> = repository.articoli.asLiveData()
fun insert(articolo: Articolo) = viewModelScope.launch {
repository.insert(articolo)
}
}
class ArticoliViewModelFactory(private val repository: ArticoliRepository): ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ArticoliViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return ArticoliViewModel(repository) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
}
【问题讨论】:
-
如果你初始化视图模型两次,你将有两个单独的实例,我认为这违背了你的目的。
-
@KristyWelsh 所以此时我应该像在示例中那样在 Activity 中执行此操作,但是一旦在 Activity 中初始化,我如何在 Fragment 中使用它?
-
是什么阻止您为每个 Fragment 使用不同类型的 ViewModel?他们都可以从同一个存储库中观察数据源
-
@IvanWooll 实际上我问的是在片段中初始化两个 ViewModel 是否是一个好习惯
-
好的,所以如果你的 Fragment 尝试先实例化它,它没有使用自定义工厂,所以它失败了。我会写一个更详细的答案。
标签: android kotlin android-fragments android-viewmodel