Я довольно новичок в android и пытаюсь следовать рекомендуемой архитектуре приложения.
Приложение в основном состоит из двух сущностей, использующих базу данных Room: базу данных и упражнения. Они имеют отношение «многие ко многим», реализованное в соответствии с предложением 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>?
Обучение не требует упражнений по умолчанию.
Теперь я хочу перечислить все тренинги в первом Master-View (просмотр повторного просмотра) и, если щелкнуть тренинг, я хочу показать соответствующие упражнения в отдельном просмотре Detail / Exercise-Recycler. Я сделал это двумя разными фрагментами, и я делюсь данными через 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 и снова запрашиваю trainingWithExercise из БД, наблюдая и отображая его. Затем при добавлении новых упражнений список обновляется корректно. Но это не лучший способ достижения моей цели или лучший способ использования viewModels.
Есть предложения?