我正在为属性列表实现搜索功能。我需要做的是查询数据库并将结果显示为用户在搜索框中键入的内容。
我所做的是每次检测到字符更改时执行搜索。像这样:
视图模型代码:
private val _properties = MutableLiveData<List<Property>>()
val properties: LiveData<List<Property>>
get() = _properties
var searchText = MutableLiveData<String>()
init {
searchText.observeForever { text ->
viewModelScope.launch(Dispatchers.IO) {
_properties.postValue(propertyRepository.searchProperties(text))
}
}
}
问题是当用户快速输入时,结果有时是错误的。因此,我定义了 asearchJob
并在每次进行另一次搜索之前取消它。像这样:
视图模型代码:
private val _properties = MutableLiveData<List<Property>>()
val properties: LiveData<List<Property>>
get() = _properties
var searchText = MutableLiveData<String>()
private lateinit var searchJob: Job
init {
searchText.observeForever { text ->
viewModelScope.launch {
if (::searchJob.isInitialized) searchJob.cancelAndJoin()
searchJob = launch(Dispatchers.IO) {
val properties = propertyRepository.searchProperties(text)
if (searchJob.isActive) {
_properties.postValue(properties)
}
}
}
}
}
这似乎工作正常。我有时会看到以前的搜索结果,但最终我得到了正确的结果。我有点担心这可能会产生什么后果。所以我想知道,有没有更好的方法来做到这一点,或者是否有更好的方法来解决这个问题?
万一有人想知道搜索是如何执行的,我的DAO
课堂上有类似以下的内容。
@Query(
"SELECT * FROM property_table WHERE code LIKE '%' || :text || '%' " +
"OR address1 LIKE '%' || :text || '%' " +
"OR address2 LIKE '%' || :text || '%' " +
"OR address3 LIKE '%' || :text || '%' " +
"OR address4 LIKE '%' || :text || '%'"
)
fun search(text: String): List<Property>