LiveData + ViewModel + Room:暴露查询返回的LiveData,该查询随时间变化(通过fts搜索)

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

我的DAO中有一个FTS查询,我想使用它在我的App中提供搜索。每次更改搜索文本时,活动都会将查询传递给视图模型。问题是,每执行一次查询,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
}

ViewModel:


    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)
}

DAO:

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>
}
android kotlin android-room android-architecture-components android-livedata
1个回答
0
投票
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
}
© www.soinside.com 2019 - 2024. All rights reserved.