【发布时间】:2019-11-10 08:23:00
【问题描述】:
我的 DAO 中有一个 FTS 查询,我想用它在我的应用程序中提供搜索。每次更改搜索文本时,活动都会将查询传递给视图模型。
问题是,Room 每次执行查询时都会返回一个LiveData,而我想在运行查询时更新相同的LiveData 对象。
我正在考虑将房间返回的LiveData 中的数据复制到我的dataSet (参见下面的代码)。这会是一个好方法吗? (如果是的话,我将如何真正做到这一点?)
到目前为止,这是我的工作:
在我的活动中:
override fun onCreate(savedInstanceState: Bundle?) {
//....
wordViewModel = ViewModelProviders.of(this).get(WordMinimalViewModel::class.java)
wordViewModel.dataSet.observe(this, Observer {
it?.let {mRecyclerAdapter.setWords(it)}
})
}
/* This is called everytime the text in search box is changed */
override fun onQueryTextChange(query: String?): Boolean {
//Change query on the view model
wordViewModel.searchWord(query)
return true
}
视图模型:
private val repository :WordRepository =
WordRepository(WordDatabase.getInstance(application).wordDao())
//This is observed by MainActivity
val dataSet :LiveData<List<WordMinimal>> = repository.allWordsMinimal
//Called when search query is changed in activity
//This should reflect changes to 'dataSet'
fun searchWord(query :String?) {
if (query == null || query.isEmpty()) {
//Add all known words to dataSet, to make it like it was at the time of initiating this object
//I'm willing to copy repository.allWordsMinimal into dataSet here
} else {
val results = repository.searchWord(query)
//Copy 'results' into dataSet
}
}
}
存储库:
//Queries all words from database
val allWordsMinimal: LiveData<List<WordMinimal>> =
wordDao.getAllWords()
//Queries for word on Room using Fts
fun searchWord(query: String) :LiveData<List<WordMinimal>> =
wordDao.search("*$query*")
//Returns the model for complete word (including the definition for word)
fun getCompleteWordById(id: Int): LiveData<Word> =
wordDao.getWordById(id)
}
道:
interface WordDao {
/* Loads all words from the database */
@Query("SELECT rowid, word FROM entriesFts")
fun getAllWords() : LiveData<List<WordMinimal>>
/* FTS search query */
@Query("SELECT rowid, word FROM entriesFts WHERE word MATCH :query")
fun search(query :String) :LiveData<List<WordMinimal>>
/* For definition lookup */
@Query("SELECT * FROM entries WHERE id=:id")
fun getWordById(id :Int) :LiveData<Word>
}
【问题讨论】:
-
你能显示wordDao的代码吗
-
@ArulMani 感谢您的关注。我猜 DAO 代码很明显可以从存储库代码中猜到。无论如何,我已将其添加到我的问题中。
-
Livedata 转换正是您所寻找的。 developer.android.com/reference/androidx/lifecycle/…
-
通过使用转换,在每次查询文本更改时,您都将“交换”实时数据,但您的观察者不需要采取行动,只会像以前一样继续观察。
-
这些方法实际上在后台使用了 Mediatorlivedata
标签: android kotlin android-room android-architecture-components android-livedata