You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Jetpack Compose界面向ViewModel同时传递选中日期与按钮数据?

解决思路:同时传递选中日期与按钮信息给ViewModel

这里给你两种最直接的实现方案,结合你现有的组件结构修改即可:


方案1:父组件维护日期状态,点击按钮时一并传递

用状态提升的思路,把选中日期的状态放在CalendarScreen中,传递给子组件ButtonsScreenCalendar,点击按钮时同时把按钮信息和日期一起传给ViewModel。

代码修改示例:

  1. CalendarScreen 中维护选中日期状态:
@Composable
fun CalendarScreen(viewModel: CalendarViewModel = viewModel()) {
    var selectedDate by remember { mutableStateOf<LocalDate?>(null) }

    // 显示DatePickerModal,选择日期后更新selectedDate
    DatePickerModal(
        onDateSelected = { date ->
            selectedDate = date
        }
    )

    // 把选中日期和点击回调传给ButtonsScreenCalendar
    ButtonsScreenCalendar(
        selectedDate = selectedDate,
        onButtonClick = { buttonInfo, date ->
            date?.let {
                viewModel.onActionTriggered(buttonInfo, it)
            } ?: run {
                // 可提示用户先选择日期
            }
        }
    )
}
  1. ButtonsScreenCalendar 接收日期和回调,传递给HomeButton:
@Composable
fun ButtonsScreenCalendar(selectedDate: LocalDate?, onButtonClick: (ButtonInfo, LocalDate?) -> Unit) {
    // 示例按钮,其他按钮同理
    HomeButton(
        buttonInfo = ButtonInfo("按钮1"),
        onClick = {
            onButtonClick(it, selectedDate)
        }
    )
}
  1. CalendarViewModel 添加接收双参数的方法:
class CalendarViewModel(private val repository: YourRepository) : ViewModel() {
    fun onActionTriggered(buttonInfo: ButtonInfo, selectedDate: LocalDate) {
        // 同时拿到按钮信息和日期,执行仓库操作
        viewModelScope.launch {
            repository.doSomething(buttonInfo, selectedDate)
        }
    }
}

方案2:ViewModel直接维护选中日期状态

把选中日期存在ViewModel里,CalendarScreen选择日期后更新ViewModel状态,点击按钮时直接调用ViewModel中已存储的日期,无需额外传递。

代码修改示例:

  1. CalendarViewModel 添加日期状态与更新方法:
class CalendarViewModel(private val repository: YourRepository) : ViewModel() {
    private val _selectedDate = MutableStateFlow<LocalDate?>(null)
    val selectedDate = _selectedDate.asStateFlow()

    fun updateSelectedDate(date: LocalDate) {
        _selectedDate.value = date
    }

    fun onTopicClick(buttonInfo: ButtonInfo) {
        // 直接取用ViewModel中的选中日期
        selectedDate.value?.let { date ->
            viewModelScope.launch {
                repository.doSomething(buttonInfo, date)
            }
        } ?: run {
            // 提示用户先选择日期
        }
    }
}
  1. CalendarScreen 观察ViewModel日期状态,选择日期时更新ViewModel:
@Composable
fun CalendarScreen(viewModel: CalendarViewModel = viewModel()) {
    val selectedDate by viewModel.selectedDate.collectAsState()

    DatePickerModal(
        onDateSelected = { date ->
            viewModel.updateSelectedDate(date)
        }
    )

    ButtonsScreenCalendar(
        onButtonClick = { buttonInfo ->
            viewModel.onTopicClick(buttonInfo)
        }
    )
}
  1. ButtonsScreenCalendar 和 HomeButton 只需传递按钮信息给ViewModel的onTopicClick即可,日期已在ViewModel中维护。

两种方案按需选择:方案1符合单向数据流的状态提升逻辑,适合简单场景;方案2把状态集中在ViewModel,适合多组件共享日期状态的场景。

内容的提问来源于stack exchange,提问作者A. Cedano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 05:42:42