Android fragments “最好的方法”;刷新“;由Room数据库提供的LiveData
我目前正在使用Room存储单词翻译列表,并将查询作为LiveData返回以监视插入和更新。然而,当我需要重新获取不同源语言的翻译时,我遇到了问题(我当前的策略是将livedata重新分配给room查询的结果) 我使用下面的SQL查询获取要翻译的语言和特定语言的翻译Android fragments “最好的方法”;刷新“;由Room数据库提供的LiveData,android-fragments,kotlin,android-room,android-lifecycle,kotlin-coroutines,Android Fragments,Kotlin,Android Room,Android Lifecycle,Kotlin Coroutines,我目前正在使用Room存储单词翻译列表,并将查询作为LiveData返回以监视插入和更新。然而,当我需要重新获取不同源语言的翻译时,我遇到了问题(我当前的策略是将livedata重新分配给room查询的结果) 我使用下面的SQL查询获取要翻译的语言和特定语言的翻译 @Dao interface TranslationDatabaseDao { ... //Returns all pairs of languages to translate to/from @Query("S
@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>>
...
}
重新分配翻译列表会导致观察livedata的片段继续观察旧的livedata,因此我的策略是在更改语言时删除观察者并在片段中重新分配它。这似乎不是最好的解决方案,我也不知道如何确保在删除前一个观察者并重新创建它之前加载了数据(我正在使用协同路由,因此我需要一种在返回livedata时进行回调的方法)
可能的解决方案
所以我的问题是:有没有更好的方法在语言更改后重新分配livedata?或者更确切地说,是否有一种可接受的方式让片段意识到这种重新分配?您可以为该语言再创建一个
LiveData
,并使用它将其映射到翻译,如:
class translationViewmodel(private val database: TranslationDatabaseDao, initLanguage: String): ViewModel() {
val language = MutableLiveData<String>("en")
val translations = language.switchMap { language ->
database.getTranslations(language)
}
...
}
谢谢,这真是太棒了!我以前认为这是不可能的,因为数据库调用应该封装在协同程序启动块中。@JJJacobs不客气。返回
LiveData
的Dao方法已经在后台线程中获取它,所以从后台线程调用它们是没有意义的。
class translationViewmodel(private val database: TranslationDatabaseDao, initLanguage: String): ViewModel() {
val language = MutableLiveData<String>("en")
val translations = language.switchMap { language ->
database.getTranslations(language)
}
...
}
viewmodel.language.value = "es"