Android MVVM+Room通过其他LiveData对象创建LiveData RecyclerViewItem对象



我有房间实体类"症状";症状的名称和id。

@Entity(tableName = "symptoms")
data class Symptom(
@PrimaryKey @NonNull val id: Int,
val name: String) {
override fun toString(): String {
return "Symptom $id: $name"
}
}

我在以下类别中得到了它:

症状道

@Dao
interface SymptomDao {
@Query("SELECT * FROM symptoms WHERE id=:id LIMIT 1")
fun getSymptom(id: Int): Symptom
@Query("SELECT * FROM symptoms")
fun getAllSymptoms(): LiveData<List<Symptom>>
}

症状库

class SymptomRepository(private val symptomDao: SymptomDao) {
fun getSymptom(id: Int) = symptomDao.getSymptom(id)
fun getAllSymptoms() = symptomDao.getAllSymptoms()
}

症状ViewModel

class SymptomsViewModel(symptomRepository: SymptomRepository): ViewModel() {
private val symptomsList = symptomRepository.getAllSymptoms()
private val symptomsItemsList: MutableLiveData<List<SymptomItem>> = MutableLiveData()
fun getAllSymptoms(): LiveData<List<Symptom>> {
return symptomsList
}
fun getAllSymptomsItems(): LiveData<List<SymptomItem>> {
return symptomsItemsList
}
}

我有一个带有复选框的RecyclerView,其中包含症状项目列表,以记住用户选择的列表症状:

data class SymptomItem(
val symptom: Symptom,
var checked: Boolean = false)

问题

我的问题是如何通过LiveData<List<Symptom>>获得LiveData<List<SymptomItem>>?我刚刚开始学习MVVM,我找不到一个简单的答案来做这件事。我已经尝试过用各种方式填写这个列表,但每次我旋转手机时,它都会丢失checked变量。如有任何提示,我将不胜感激。

您需要通过将ID存储在ViewModel中的List中来存储要检查的项。然后,您将组合Symptom对象的列表和要检查的项目的列表,并生成SymptomItem对象的列表。

我将使用Kotlin Flow来实现这一点。

@Dao
interface SymptomDao {
@Query("SELECT * FROM symptoms")
fun flowAllSymptoms(): Flow<List<Symptom>>
}
class SymptomRepository(private val symptomDao: SymptomDao) {
fun flowAllSymptoms() = symptomDao.flowAllSymptoms()
}
class SymptomsViewModel(
private val symptomRepository: SymptomRepository
) : ViewModel() {
private val symptomsListFlow = symptomRepository.flowAllSymptoms()
private val symptomsItemsList: MutableLiveData<List<SymptomItem>> = MutableLiveData()
private var checkedIdsFlow = MutableStateFlow(emptyList<Int>())
init {
viewModelScope.launch {
collectSymptomsItems()
}
}
private suspend fun collectSymptomsItems() =
flowSymptomsItems().collect { symptomsItems ->
symptomsItemsList.postValue(symptomsItems)
}
private fun flowSymptomsItems() =
symptomsListFlow
.combine(checkedIdsFlow) { list, checkedIds ->
list.map { SymptomItem(it, checkedIds.contains(it.id)) }
}
fun checkItem(id: Int) {
(checkedIdsFlow.value as MutableList<Int>).add(id)
checkedIdsFlow.value = checkedIdsFlow.value
}
fun uncheckItem(id: Int) {
(checkedIdsFlow.value as MutableList<Int>).remove(id)
checkedIdsFlow.value = checkedIdsFlow.value
}
fun getSymptomsItems(): LiveData<List<SymptomItem>> {
return symptomsItemsList
}
}

在Fragment中,观察getSymptomsItems()并更新适配器数据。

代码没有经过测试,您可能需要进行小的调整才能编译它

最新更新