我想使用SearchView搜索房间db中的某些元素,这是有问题的,因为我无法在RecyclerViewAdapter中使用getFilter,因为我有ViewModel,也许谁知道如何在一个项目中组合所有这些元素。我使用Transormations.switchMap搜索一种方法。但是我无法连接它们。
ProductViewModel
class ProductViewModel(application: Application) : AndroidViewModel(application) {
private val repository: ProductRepository
val allProducts: LiveData<List<ProductEntity>>
private val searchStringLiveData = MutableLiveData<String>()
init {
val productDao = ProductsDB.getDatabase(application, viewModelScope).productDao()
repository = ProductRepository(productDao)
allProducts = repository.allProducts
searchStringLiveData.value = ""
}
fun insert(productEntity: ProductEntity) = viewModelScope.launch {
repository.insert(productEntity)
}
val products = Transformations.switchMap(searchStringLiveData) { string ->
repository.getAllListByName(string)
}
fun searchNameChanged(name: String) {
searchStringLiveData.value = name
}
}
ProductDao
interface ProductDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun insertProduct(productEntity: ProductEntity)
@Query("SELECT * from products")
fun getListAllProducts(): LiveData<List<ProductEntity>>
@Query("DELETE FROM products")
suspend fun deleteAll()
@Query("SELECT * FROM products where product_name_ent LIKE :name or LOWER(product_name_ent) like LOWER(:name)")
fun getListAllByName(name: String):LiveData<List<String>>
}
ProductDao
@Query("SELECT * FROM products where product_name_ent LIKE :name or LOWER(product_name_ent) like LOWER(:name)")
fun getListAllByName(name: String):LiveData<List<ProductEntity>>
您的域中的此方法应返回(*),并选择not特定列。类似于(LiveData<List<ProductEntity>>
而不是LiveData<List<String>>
,因为此查询从实体中选择everything
@Query("SELECT * from products") fun getListAllProducts():LiveData<List<ProductEntity>>
)ProductViewModel
class ProductViewModel(application: Application) : AndroidViewModel(application) {
private val repository: ProductRepository
init {
val productDao = ProductsDB.getDatabase(
application,
viewModelScope
).productDao()
repository = ProductRepository(productDao)
}
private val searchStringLiveData = MutableLiveData<String>("") //we can add initial value directly in the constructor
val allProducts: LiveData<List<ProductEntity>>=Transformations.switchMap(searchStringLiveData)
{
string->
if (TextUtils.isEmpty(string)) {
repository.allProducts()
} else {
repository.allProductsByName(string)
}
}
fun insert(productEntity: ProductEntity) = viewModelScope.launch {
repository.insert(productEntity)
}
fun searchNameChanged(name: String) {
searchStringLiveData.value = name
}
}
...使用其他方法,添加以下内容:存储库
fun allProducts():LiveData<List<ProductEntity>>=productDao.getListAllProducts()
fun allProductsByNames(name:String):LiveData<List<ProductEntity>>=productDao.getListAllByName(name)
在onCreate()中(如果它是一个活动)在您的活动或具有recyclerview适配器的片段中
viewModel.allProducts.observe(this,Observer{products->
//populate your recyclerview here
})
或
onActivityCreated(if it is a fragment) viewModel.allProducts.observe(viewLifecycleOwner,Observer{products-> //populate your recyclerview here })
现在将一个侦听器设置为searchView,每次用户提交查询时,调用viewModel.searchNameChanged(//传递新值)希望这会有所帮助
问候,