如何在房间中使用LiveData和ViewModel使用SearchView

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

我想使用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>>

}
android kotlin viewmodel searchview
1个回答
0
投票

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>>
您的域中的此方法应返回LiveData<List<ProductEntity>>而不是LiveData<List<String>>,因为此查询从实体中选择

everything

(*),并选择not特定列。类似于(@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)

在您的活动或具有recyclerview适配器的片段中

在onCreate()中(如果它是一个活动)

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(//传递新值)

希望这会有所帮助

问候,

© www.soinside.com 2019 - 2024. All rights reserved.