[英]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.