传递LiveData到ViewModel构造函数有效吗?



我正在构建一个使用MVVM与房间的应用程序,其中数据列表显示在一个活动中。列表从LiveData对象中的Room数据库中获得,并在活动中观察。

当想要向列表中添加另一个项目时,显示一个DialogFragment,提示用户从可能的值列表中选择一个值,但是,如果选择的值已经存在于数据库中,它将不允许用户按对话框的积极按钮。

我已经为Activity和DialogFragment实现了单独的ViewModels。两个视图模型分别调用访问数据库中的数据,尽管它们总是查看相同的数据。这对我来说似乎有点多余,所以我想知道,使两个视图模型共享相同数据的最佳方法是什么,只有一个调用从数据库中获取数据。

我得到的一个想法是在DialogFragment构造函数中为LiveData添加一个参数,然后在创建DialogFragment视图模型时,我将传递包含列表的LiveData的引用,从活动视图模型中获得。

class AddItemDialogVewModel(items: LiveData<List<Item>>) :
ViewModel() {
//check if item to be added already exists in items
}

为ViewModel创建一个Factory类,然后在DialogFragment中:

val dialogViewModel = ViewModelProvider(this, new AddItemViewModelFactory(activityViewModel.items))
.get(AddItemDialogViewModel.class);

有没有人看到任何问题,有没有更好的方法来做到这一点。我以前从未见过这样做,所以我不确定这是否是一个好的练习。

感谢

如果activity和fragment从数据库中的一个表中显示相同的数据,那么用户选择的值将始终显示在数据库中。

你想在这里达到什么目的?

顺便说一下,如果那是你真正想做的,你不需要为对话片段实现ViewModel。你可以使用来自父活动的共享ViewModel。

您使用共享LiveData的方法是正确的。但是在构造函数中传递它并不是正确的方法。

我将使用Kotlin属性委托的ViewModels。添加这些依赖项:

implementation "androidx.fragment:fragment-ktx:1.4.1"
implementation "androidx.activity:activity-ktx:1.4.0"

ViewModel活动

class ItemsActivityViewModel : ViewModel() {
private val _items = MutableLiveData<List<Item>>()
val items: LiveData<List<Item>> get() = _items
.
.
.
// Get data from Room Database ...
}

活动
class ItemsActivity : AppCompatActivity() {
private val viewModel by viewModels<ItemsActivityViewModel>() // Can only be use with an empty constructor ViewModel
override fun onCreate(savedInstanceState:Bundle) {
super.onCreate(savedInstanceState)
viewModel.items.observe(this) { items ->
// Do something
}
}
}

片段

class AddItemDialogFragment : DialogFragment() {
private val activityViewModel by activityViewModels<ItemsActivityViewModel>()
override fun onViewCreated(view:View, savedInstanceState:Bundle) {
activityViewModel.items.observe(viewLifecycleOwner) { items ->
// Do something
}
}
}

或者你可以从ViewModelProvider创建你的ViewModel。

活动
class ItemsActivity : AppCompatActivity() {
lateinit var viewModel: ItemsActivityViewModel
override fun onCreate(savedInstanceState:Bundle) {
super.onCreate(savedInstanceState)
viewModel = ... // Create your ViewModel
viewModel.items.observe(this) { items ->
// Do something
}
}
}

片段

class AddItemDialogFragment : DialogFragment() {
private lateinit var activityViewModel: ItemsActivityViewModel
override fun onCreate(savedInstanceState:Bundle) {
super.onCreate(savedInstanceState)
activityViewModel = (requireActivity() as ItemsActivity).viewModel
}
override fun onViewCreated(view:View, savedInstanceState:Bundle) {
activityViewModel.items.observe(viewLifecycleOwner) { items ->
// Do something
}
}
}

最新更新