android - LiveData + ViewModel + Room:公开查询返回的 LiveData 随时间变化(通过 fts 搜索)
问题描述
我的 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>
}
解决方案
val dataSet :LiveData<List<WordMinimal>>
val searchQuery = MutableLiveData<String>()
init {
dataSet = Transformations.switchMap(searchQuery) { query ->
if (query == null || query.length == 0) {
//return WordRepository.getAllWords()
} else {
//return WordRepository.search(query)
}
}
}
fun setSearchQuery(searchedText: String) {
searchQuery.value = searchedText
}
推荐阅读
- php - 从数组中查找数据并对数组中可用日期的一些字段求和
- amazon-web-services - 使用 AWS 或 ASK CLI 创建完整的 Alexa 技能
- javascript - 如何使用 javascript 强制我的 svg 的笔画宽度
- c++ - 唯一枚举键和随机值的 C++ 容器
- emacs - Windows 和 Crostini 中的组织捕获模板可移植性
- java - 编译失败:找不到模块:org.apache.logging.log4j
- flask - 收到 post 请求后返回什么
- python - 使用 DECLARE 抛出无效的 SQL 语句
- json - Logstash json 字段删除
- angular - 使用 matDatepickerFilter 过滤多个视图的日期