在LiveData和MVVM架构方面,我完全是个新手。我正试图弄清楚如何观察LiveData在ViewModel中更新另一个变量,取决于它是否为空。
我用这个从我的房间数据库中获得LiveData:
class MealsViewModel @Inject constructor(
private val mealDao : MealDao
) : ViewModel() {
...
private val currentDay: MutableLiveData<Date> = MutableLiveData(Date())
val meals = Transformations.switchMap(currentDay){ date -> mealDao.getMeals(date).asLiveData() }
我希望ViewModel中的另一个变量private val empty: Boolean
在列表返回空(null)时更新。这将用于从可见片段中更新ImageView。
如何同步查看val meals
是否为空?
我四处阅读,看到一些人说要使用observeForever
,但架构指南明确建议不要在ViewModels中使用任何观察者。
我可能会观察片段中的LiveData,但这需要片段中的业务逻辑,即:
viewModel.meals.observe(viewLifecycleOwner) {
if meals.value.isEmpty() imageView.visibility = View.VISIBLE else imageView.visibility = View.GONE
}
我想保持片段为"哑巴"尽可能,所以我更喜欢在ViewModel的逻辑。这可能吗?
您可以检查实时数据meal
,看看它是空的还是空的,然后触发您的实时数据empty
,像这样:
isEmptyMeals
。当meals
值发生变化时,这个实时数据变量将始终触发,并检查您的meals
值是否为空或null。
MealsViewModel.kt
class MealsViewModel @Inject constructor(
private val mealDao : MealDao
) : ViewModel() {
...
private val currentDay: MutableLiveData<Date> = MutableLiveData(Date())
val meals = Transformations.switchMap(currentDay){ date -> mealDao.getMeals(date).asLiveData() }
val isEmptyMeals = meals.map {
it.isNullOrEmpty()
}
}
在片段中,您将监听观察livedataisEmptyMeals
并执行逻辑来隐藏或显示您想要的图像视图。
Fragment.kt
viewModel.isEmptyMeals.observe(viewLifecycleOwner) {
imageView.visibility = if (it) View.VISIBLE else View.GONE
}
我不知道你的代码是如何设置的,但是你可以在
下面做一些事情添加变量到ViewModel
val empty = MutableLiveData<Boolean>()
在meals
观察者viewModel.meals.observe (viewLifecycleOwner) {
viewModel.empty,postValue(meals.value.isEmpty())
从empty
观察使用MediatorLiveData
在ViewModel类中创建
val empty = MediatorLiveData<Boolean>()
然后
empty.addSource(meals) {
empty.value = it.isEmpty()
}