我对以下场景有点困惑:
最初,我在屏幕上显示一个 DatePicker 模式。
当用户选择一个日期时,我会显示几个按钮。
当用户点击任意一个按钮时,我都希望向 ViewModel 传递两条数据:选定的日期和按下的按钮类型,以便根据这两个条件在存储库中搜索数据。
我的问题是,在包含 ViewModel 之前,我找不到传递这两条数据的方法。
我正在尝试做类似InterestsScreen
Now In Android 的事情。
我在另一个场景中有一个类似的代码,它可以工作,但那里的日期是从系统中获取的,所以没有问题。这里的日期必须由用户从 DatePicker 中提供。
我没有展示 UseCase 或 Repository 的代码,当我向其传递正确的参数时,该代码可以正常工作。我的问题是,当我有选定的日期和用户按下的按钮类型时,我不知道如何调用 ViewModel。
我展示了我的代码的相关部分:
NavGraphBuilder
composable<CalendarRoute> {
CalendarScreen(onTopicClick = onTopicClick,onDateSelected={})
CalendarScreen
(从 NavGraphBuilder 调用)
@Composable
fun CalendarScreen(
onTopicClick: (String) -> Unit,
onDateSelected: (Long?) -> Unit,
viewModel: CalendarViewModel = hiltViewModel()
) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
DatePickerAndButtons(
onTopicClick = viewModel::onTopicClick,
onDateSelected = viewModel::onDateSelected,
uiState = uiState
)
}
DatePickerAndButtons
@ExperimentalLayoutApi
@Composable
fun DatePickerAndButtons(
onTopicClick: (String) -> Unit,
onDateSelected: (Long?) -> Unit,
uiState: CalendarUiState
) {
var showTopics by remember { mutableStateOf(false) }
var showDatePicker by remember { mutableStateOf(true) }
var selectedDate by remember { mutableStateOf<Long?>(null) }
when (uiState) {
CalendarUiState.Empty -> Text("Empty")
CalendarUiState.Error -> Text("Error")
CalendarUiState.Loading -> {
Text("Loading")
//showDatePicker=true
}
is CalendarUiState.CalendarData -> {
showTopics=false
//showDatePicker=false
if(uiState.topics.isNotEmpty()) {
//Show data
}else{
//¿?
}
}
}
if (selectedDate != null) {
val date = Date(selectedDate!!)
val formattedDate = SimpleDateFormat("MMM dd, yyyy", Locale.getDefault()).format(date)
Text("Selected date: $formattedDate")
} else {
Text("No date selected")
}
if (showDatePicker) {
DatePickerModal(
onDateSelected = {
selectedDate = it
onDateSelected(it)
//viewModel.onDateSelected(selectedDate)
showDatePicker = false
showTopics=true
},
onDismiss = { showDatePicker = false }
)
}
if(showTopics) {
//Code that create buttons to be clicked
}
}
ViewModel
@HiltViewModel
class CalendarViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
val userDataRepository: UserDataRepository,
val universalisRepository: UniversalisRepository,
getTopicWithDate: GetUniversalisFromCalendarUseCase,
) : ViewModel() {
private val selectedTopicIdKey = "selectedTopicIdKey"
private val selectedDateKey = "selectedDateKey"
private val calendarRoute: CalendarRoute = savedStateHandle.toRoute()
private val selectedTopicId = savedStateHandle.getStateFlow(
key = selectedTopicIdKey,
initialValue = "1" //calendarRoute.topicId,
)
private val selectedDate = savedStateHandle.getStateFlow(
key = selectedDateKey,
initialValue = 0
)
val uiState: StateFlow<CalendarUiState> = combine(
selectedTopicId,
getTopicWithDate.invoke(
date = selectedDate.value,
title = "TODO:Title",
selectedTopicId = selectedTopicId.value
),
CalendarUiState::CalendarData,
).
stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = CalendarUiState.Loading,
)
fun onTopicClick(topicId: String?) {
savedStateHandle[selectedTopicIdKey] = topicId
}
fun onDateSelected(date: Long?) {
savedStateHandle[selectedDateKey] = date
}
}
您错误地组合了两个不同的流程阶段。
和
topicId
是date
主题的查询参数,因此只有当它们发生变化时查询才会开始。因此您的主题查询结果将如下所示:
那么你的
uiState
意愿是: