![](/img/trans.png)
[英]Android viewModel and Kotlin: Who is the viewModel data shared with?
[英]Android [Kotlin] - Inserting a new item into a selected Child-List on a MasterDetail-Flow using shared viewModel
我对 android 很陌生,我正在尝试遵循推荐的应用程序架构。
该应用程序基本上由两个使用房间数据库的实体组成:培训和练习。 它们具有多对多关系,按照 android 开发人员指南中的建议实现,并带有一个额外的参考实体和一个 POJO:
@Entity(
tableName = "training_exercise_ref",
primaryKeys = ["trainingId", "exerciseId"])
data class TrainingExerciseCrossRef (
var trainingId: Long,
var exerciseId: Long
)
data class TrainingWithExercise (
@Embedded val training: Training,
@Nullable
@Relation(
parentColumn = "trainingId",
entityColumn = "exerciseId",
associateBy = Junction(TrainingExerciseCrossRef::class)
)
val exercises: List<Exercise>?
默认情况下,培训不需要练习。
现在我想在第一个主视图(recyclerview)中列出所有培训,如果点击培训,我想在单独的 Detail/Exercise-Recyclerview 中显示相应的练习。 我通过两个不同的片段完成了此操作,并且按照开发人员指南中的建议通过 ViewModel 共享数据:
class DashboardViewModel(application: Application) : AndroidViewModel(application) {
private val trainingRepository: TrainingRepository
val allTrainingWithExercises: LiveData<List<TrainingWithExercise>>
val selectedTraining = MutableLiveData<TrainingWithExercise>()
init {
val trainingDao = TrainingRoomDatabase.getDatabase(application, viewModelScope).trainingDao()
trainingRepository = TrainingRepository(trainingDao)
allTrainingWithExercises = trainingRepository.allTrainingWithExerciseEntries
}
fun selectTraining(trainingWithExercise: TrainingWithExercise) {
selectedTraining.value = trainingWithExercise
}
fun insertExerciseToTraining(trainingId: Long, exercise: Exercise) = viewModelScope.launch {
val newExerciseId: Long = exerciseRepository.insert(exercise)
trainingRepository.insertExerciseOfTraining(trainingId, newExerciseId)
}
所以,当我点击一个训练时,我将选择保存在 viewModel 中,试图在片段中设置一个观察者
dashboardViewModel.selectedTraining.observe(viewLifecycleOwner, Observer { exercises ->
exercises?.let { adapter.setTraining(it) }
})
并在详细信息片段中显示所选训练和练习列表。 在细节片段中,我还希望能够插入新的练习。
我的问题来了:
当我添加新练习时,我使用上面的“insertExerciseToTraining”函数,然后在存储库中插入练习和新的 trainingExerciseCrossRef。 但是在细节片段中,练习列表没有更新。 只有当我回到训练概览并再次选择训练时。 这甚至是使用共享视图模型的正确方法吗?
作为快速修复,我只在 viewModel 中共享训练 id 并再次从数据库查询 trainingWithExercise,观察并显示它。 然后,在插入新练习时,列表会正确更新。 但这似乎不是实现我的目标的最佳方式或使用 viewModels 的最佳方式。
有什么建议?
我想出了一个解决方法,但我不确定这是否是最佳实践。 也许有更清洁的方法; 但它的工作。
所以基本上,如上所述,我正在选择训练,并将选择的 id 保存到 viewModel 中。 然后我启动详细信息片段,并观察完整的 allTrainingWithExercise-List/LiveData,然后使用先前保存的 ID 过滤该列表以进行训练,并将其设置在视图中。
因此,当我通过插入新练习来更新训练的练习列表时,观察到的 allTrainingsWithExercise 会得到更新,并且我正在通过保存的训练 ID“重新选择”训练。
dashboardViewModel.allTrainingWithExercises.observe(viewLifecycleOwner, Observer { trainings ->
trainings?.let { adapter.setTraining(it.filter { it.training.trainingId == dashboardViewModel.selectedTrainingId }[0]) }
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.