class HomeViewModel(
savedStateHandle: SavedStateHandle,
private val categoryRepository: CategoryRepository,
private val expenseRepository: ExpenseRepository
): ViewModel() {
private val month: Int = savedStateHandle[HomeDestination.monthArgs] ?: Calendar.MONTH
private val year: Int = savedStateHandle[HomeDestination.yearArgs] ?: Calendar.YEAR
private val _categories: Flow<List<Category>> = categoryRepository.getAllCategoriesStream()
private val _expenses: Flow<List<Expense>> = expenseRepository.getAllExpensesBetweenStream(
LocalDate.of(year, month, 1).toEpochDay(),
LocalDate.of(year, if (month + 1 == 13) 1 else month + 1, 1).toEpochDay()
)
private var _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
data class UiState(
val categories: List<CategoryUiState> = listOf(),
val expenses: List<ExpenseUiState> = listOf()
)
}
我想将 _expenses
的值链接到
expenses
中的
UiState
并执行此操作,以便在
_expenses
内容更新时更新费用。
Expense
对象存储为
ExpenseUiState
,我希望有一些辅助函数可以从
UiState
和
Category
创建正确的
Expense
。我们称之为
UiState.of(...)
。然后您可以将
_uiState
和
uiState
替换为:
val uiState: StateFlow<UiState> = combine(_categories, _expenses) { category, expenses ->
UiState.of(category, expenses)
}.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = UiState.Default,
)
这使用 UiState.of
将多个流合并为单个流以创建结果内容。然后将其转换为
StateFlow
。这需要一个初始值,所以我发明了一个
UiState.Default
。将其替换为您希望流程返回的任何内容,直到从
_categories
和
_expenses
生成第一个值。如果你愿意的话,可以是
null
。