【发布时间】:2021-04-03 04:18:55
【问题描述】:
我正在使用带有 MVVM 模式的房间数据库创建一个 android 应用程序,问题是我在获取数据时无法使用多个查询。我可以获取一次数据,但是我不能再这样做了。
DAO 接口:
@Dao
interface StockDao {
@Insert
suspend fun insert(stock:Stock)
@Update
suspend fun update(stock:Stock)
@Delete
suspend fun delete(stock:Stock)
@Query("DELETE FROM stock_table")
suspend fun deleteAll()
@Query("SELECT * FROM stock_table")
fun selectAll():Flow<List<Stock>>
@Query("SELECT * FROM stock_table WHERE isFinished = 0")
fun selectAllUnfinished(): Flow<List<Stock>>
@Query("SELECT * FROM stock_table WHERE isFinished = 1")
fun selectAllFinished():Flow<List<Stock>>
@Query("SELECT * FROM stock_table ORDER BY totalSpent DESC")
fun selectAllOrderByDesc():Flow<List<Stock>>
@Query("SELECT * FROM stock_table ORDER BY totalSpent ASC")
fun selectAllOrderByAsc():Flow<List<Stock>>
}
存储库:
class StockRepository(private val stockDao: StockDao) {
private lateinit var allStock: Flow<List<Stock>>
suspend fun insert(stock: Stock) {
stockDao.insert(stock)
}
suspend fun update(stock: Stock) {
stockDao.update(stock)
}
suspend fun delete(stock: Stock) {
stockDao.delete(stock)
}
suspend fun deleteAll() {
stockDao.deleteAll()
}
fun selectAll(): Flow<List<Stock>> {
allStock = stockDao.selectAll()
return allStock
}
fun selectAllOrderByDesc(): Flow<List<Stock>> {
allStock = stockDao.selectAllOrderByAsc()
return allStock
}
fun selectAllOrderByAsc(): Flow<List<Stock>> {
allStock = stockDao.selectAllOrderByAsc()
return allStock
}
fun selectAllFinished(): Flow<List<Stock>> {
allStock = stockDao.selectAllFinished()
return allStock
}
fun selectAllUnfinished(): Flow<List<Stock>> {
allStock = stockDao.selectAllUnfinished()
return allStock
}
}
Viewmodel 类:
class StockViewModel(private val repo: StockRepository) : ViewModel() {
companion object {
const val ALL = 0
const val ORDER_BY_DESC = 1
const val ORDER_BY_ASC = 2
const val FINISHED = 3
const val UNFINISHED = 4
}
var allStocks = repo.selectAll().asLiveData()
fun insert(stock: Stock) = viewModelScope.launch {
repo.insert(stock)
}
fun update(stock: Stock) = viewModelScope.launch {
repo.update(stock)
}
fun delete(stock: Stock) = viewModelScope.launch {
repo.delete(stock)
}
fun deleteAll() = viewModelScope.launch {
repo.deleteAll()
}
fun selectAllStockWithFilter(filter: Int): LiveData<List<Stock>> {
when (filter) {
ALL -> allStocks = repo.selectAll().asLiveData()
ORDER_BY_DESC -> allStocks = repo.selectAllOrderByDesc().asLiveData()
ORDER_BY_ASC -> allStocks = repo.selectAllOrderByAsc().asLiveData()
FINISHED -> allStocks = repo.selectAllFinished().asLiveData()
UNFINISHED -> allStocks = repo.selectAllUnfinished().asLiveData()
}
return allStocks
}
class StockViewModelFactory(private val repo: StockRepository) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(StockViewModel::class.java)) {
@Suppress("UNCHECKED_CAST")
return StockViewModel(repo) as T
}
throw IllegalArgumentException("Unknown viewModel class")
}
}
}
应用类:
class FinanceApplication :Application(){
private val database by lazy { FinanceDatabase.getInstance(this)}
val stockRepository by lazy { StockRepository(database.stockDao()) }
}
使用此视图模型的活动:
class StocksActivity : AppCompatActivity() {
//Layout components
private lateinit var binder: ActivityStocksBinding
private lateinit var recyclerView: RecyclerView
private lateinit var recyclerViewAdapter: StockAdapter
//ViewModel
private val viewModel: StockViewModel by viewModels {
StockViewModel.StockViewModelFactory((application as FinanceApplication).stockRepository)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binder = ActivityStocksBinding.inflate(layoutInflater)
setContentView(binder.root)
fetchStocks()
}
private fun fetchStocks() {
viewModel.allStocks.observe(this) {
recyclerViewAdapter.submitList(it)
}
}
private fun initRecyclerViewLayout() {
val recyclerViewLayoutBinder = binder.includedLayout
recyclerView = recyclerViewLayoutBinder.stocksRecyclerView
recyclerViewAdapter = StockAdapter(this)
recyclerView.adapter = recyclerViewAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(true)
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_stock_toolbar, menu)
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.menu_stock_toolbar_filter_all -> viewModel.selectAllStockWithFilter(StockViewModel.ALL)
R.id.menu_stock_toolbar_filter_maior_menor -> viewModel.selectAllStockWithFilter(StockViewModel.ORDER_BY_DESC)
R.id.menu_stock_toolbar_filter_menor_maior -> viewModel.selectAllStockWithFilter(StockViewModel.ORDER_BY_ASC)
R.id.menu_stock_toolbar_filter_finalized -> viewModel.selectAllStockWithFilter(StockViewModel.FINISHED)
R.id.menu_stock_toolbar_filter_opened -> viewModel.selectAllStockWithFilter(StockViewModel.UNFINISHED)
}
return true
//NOTHIN HAPPENS AFTER CHOOSING ONE
}
}
当我进入活动时,所有数据都会正常获取,但是当我单击菜单项对其应用一些过滤器时,什么也没有发生,数据不会改变。我该如何解决这个问题?
【问题讨论】:
-
在
StocksActivity.fetchStocks()中,最初的“全部”结果通过observe()'ing ViewModel 返回的LiveData 显示。从选项菜单中选择后,新的过滤结果observe()'ed 怎么样? -
@homerman 当我点击一个菜单项时,
StocksActivity.fetchStocks()方法将`allStock` 变量从StocksViewmodel.. 至少这是意图,还是我想错了?跨度>
标签: android android-studio android-room android-mvvm