В настоящее время я использую Room для хранения списка переводов слов и возвращаю запросы в виде LiveData для отслеживания вставок и обновлений. Однако я сталкиваюсь с проблемами, когда мне нужно повторно получить переводы для другого исходного языка (моя текущая стратегия состоит в том, чтобы переназначить жилые данные в результате запроса помещения).
Я выбираю языки для переводаи переводы для конкретного языка с использованием приведенных ниже SQL-запросов
@Dao
interface TranslationDatabaseDao {
...
//Returns all pairs of languages to translate to/from
@Query("SELECT * FROM language_pairs")
fun getAllLanguagePairs(): LiveData<List<LanguagePair>>
//Returns translations with the specified source language
@Query("SELECT * FROM translations WHERE sourceLanguage = :language")
fun getTranslations(language: String): LiveData<List<TranslationResult>>
...
}
, которые я вызываю при создании экземпляра модели представления, и снова при смене языка пользователем (см. changeLanguage(...)
ниже).
class translationViewmodel(private val database: TranslationDatabaseDao, initLanguage: String): ViewModel() {
...
val languages: LiveData<List<LanguagePair>> = database.getAllLanguagePairs()
val currentLanguages = Transformations.map(languages) { allLanguages ->
allLanguages?.let {
it[0] //Get the first language in the list
}
}
var translations: LiveData<List<TranslationResult>> = database.getTranslations(initLanguage)
...
fun changeLanguage(language: String) {
coroutinesScope.launch {
translations = withContext(Dispatchers.IO) {
database.getTranslations(language)
}
}
}
...
}
Повторное назначение списка переводов приводит к тому, что фрагмент, наблюдающий жизненные данные, продолжает наблюдать старые живые данные, поэтому моя стратегия заключалась в том, чтобы удалить наблюдателя и переназначить его во фрагменте при смене языков. Это не кажется лучшим решением здесь, и я также не уверен, как обеспечить загрузку данных перед удалением предыдущего наблюдателя и его повторным созданием (я использую сопрограммы, поэтому мне нужен способ обратного вызовакогда жилатата была возвращена).
Возможные решения
- Пусть база данных выдаст только объект List, а не livingata. Я мог бы затем сохранить его в изменяемой среде. Это не идеально, поскольку вставки и обновления не отражаются в возвращаемом списке автоматически, поэтому мне придется повторно выбирать данные каждый раз, когда я изменяю список переводов для определенного языка.
- Выбрать всепереводы, а затем фильтровать их каждый раз, когда язык меняется. Это будет немного ресурсоемким, как только список языков увеличится.
Итак, мой вопрос: есть ли лучший способ переназначения liveata после смены языка? Или, скорее, существует ли приемлемый способ, чтобы фрагмент был осведомлен об этом переназначении?