“刷新”会议室数据库提供的实时数据的最佳方法

问题描述 投票:0回答:1

我目前正在使用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)
         }
      }
   }

   ...
}

重新分配翻译列表会导致观察实时数据的片段继续观察旧的实时数据,因此我的策略是删除观察者,并在更改语言时将其重新分配到片段中。这似乎不是最好的解决方案,而且我也不确定在删除先前的观察者并重新创建之前如何确保数据已加载(我正在使用协程,因此我需要一种回调方法实时数据返回时)。

可能的解决方案

  1. 让数据库仅返回一个List对象,而不返回livedata。然后,我可以将其存储在可变的livedata中。这不是理想的选择,因为插入和更新不会自动反映在返回的列表中,因此,每次更改特定语言的翻译列表时,我都必须重新获取数据。
  2. 获取所有翻译,然后在每次语言更改时对其进行过滤。一旦语言列表变大,这将占用大量资源。

所以我的问题是:有没有更好的方法可以在更改语言后重新分配实时数据?或者更确切地说,是否存在使片段了解此重新分配的可接受方法?

android-fragments kotlin android-room android-lifecycle kotlin-coroutines
1个回答
0
投票

您可以为该语言再创建一个LiveData,然后使用switchMap将其映射到翻译,例如:

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"
© www.soinside.com 2019 - 2024. All rights reserved.