所以我有一个挂起函数,我从协程调用,并带有过滤条件。 然后,此过滤条件将被传递到视图模型,更具体地说是传递到查询。 所有这些都存储在 ui-state 中,该状态正在我的主屏幕中使用“.collectasState()”使用。根据过滤器是否激活,存储在 ui-state 中的收集实体将显示在 LazyColumn 中。问题是,当我执行过滤器时没有任何反应,它总是显示通常显示的内容(数据库中的实体,未过滤)。 当我尝试打印出来,看看是否有实体被过滤时,我得到这个:
2023-12-17 19:58:39.316 9995-9995 FilterListComplete com.example.myapplication D 过滤结果:[]
如果有人能告诉我我在这里做错了什么,我将非常感激!
这是我的视图模型:
class FilterProductViewModel(private val productRepository: ProductRepository) : ViewModel() {
private var _filterProductUiState: StateFlow<FilterProductUiState> = MutableStateFlow(FilterProductUiState())
val filterProductUiState: StateFlow<FilterProductUiState> get() = _filterProductUiState
private var isFilterActive = false
fun isFilterActive(): Boolean {
return isFilterActive
}
suspend fun applyProductFilter(
category: List<Category?>,
currency: String,
startPrice: Double,
endPrice: Double,
startDate: String,
endDate: String,
company: String
) {
isFilterActive = true
val _filterProductUiState: StateFlow<FilterProductUiState> = productRepository.filterProducts(
category = category,
currency = currency,
startPrice = startPrice,
endPrice = endPrice,
startDate = startDate,
endDate = endDate,
company = company
).map { FilterProductUiState(it) }
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(TIMEOUT_MILLIS),
initialValue = FilterProductUiState()
)
Log.d("FilterListComplete", "Filtered Results: ${filterProductUiState.value}")
}
companion object {
private const val TIMEOUT_MILLIS = 5_000L
}
}
data class FilterProductUiState(val filterProductList: List<Product> = listOf())
这是我在 DAO 中的查询:
"SELECT * FROM Product " +
"WHERE category IN (:categoryList) " +
"AND currency = :currency " +
"AND price >= :startPrice " +
"AND price <= :endPrice " +
"AND date >= :startDate " +
"AND date <= :endDate " +
"AND company = :company " +
"ORDER BY category DESC"
)
fun filterProducts(
categoryList: List<Category?>,
currency: String?,
startPrice: Double?,
endPrice: Double?,
startDate: String?,
endDate: String?,
company: String?
): Flow<List<Product>>
在
applyProductFilter()
中,您没有更新Viewmodel的变量_filterProductUiState
,您正在为方法范围创建一个新的变量区域设置,因为您在其中将其定义为val _filterProductUiState
。为了替换它,您需要重新分配它,而不预先使用 val
。但在这种情况下,还会存在一个问题,就好像您的 UI 收集初始 StateFlow 时,它不会收集第二个 StateFlow(至少会立即收集,不确定重组是否会重新订阅新实例),因为它已经更改了实例。
一个快速解决方案:在
map { FilterProductUiState(it) }
内部更新状态流的实例,如map { _filterProductUiState.update { _ -> FilteredProductUiState(it) } }
。并且无需在方法中声明 filterProductUiState
。
还要确保按原样声明您的私有 MutableStateFlow :
private var _filterProductUiState: MutableStateFlow<FilterProductUiState> = MutableStateFlow(FilterProductUiState())
。