如何在Kotlin Jetpack Compose中获取DateRangePicker选中日期并赋值
解决Jetpack Compose DateRangePicker选中日期获取问题
要实现从DateRangePicker获取选中日期并赋值给periodStart和periodEnd,需要调整代码逻辑,核心是正确使用DateRangePickerState跟踪选中状态,并在确认选择时更新变量。以下是修改后的完整实现:
修改后的代码
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.material3.Button import androidx.compose.material3.CalendarLocale import androidx.compose.material3.DatePickerDialog import androidx.compose.material3.DateRangePicker import androidx.compose.material3.DateRangePickerState import androidx.compose.material3.DisplayMode import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.alele.datepickertemplate.ui.theme.DatePickerTemplateTheme import java.time.LocalDateTime import java.time.ZoneId @OptIn(ExperimentalMaterial3Api::class) @Composable fun DatePickerTemplate(){ var showDatePicker by remember { mutableStateOf(false) } // 修正:将periodEnd改为var,支持后续赋值更新 var periodStart by remember { mutableStateOf(LocalDateTime.now()) } var periodEnd by remember { mutableStateOf(LocalDateTime.now()) } // 关键:将DateRangePickerState提出来remember,保持状态一致性 val dateRangePickerState = remember { DateRangePickerState( initialSelectedStartDateMillis = periodStart.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), initialSelectedEndDateMillis = periodEnd.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), initialDisplayedMonthMillis = null, yearRange = 2023..2023, initialDisplayMode = DisplayMode.Picker, locale = CalendarLocale("UK") ) } Column( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, modifier = Modifier ){ Button(onClick = { showDatePicker = true }) { Text(text = "From $periodStart") } Button(onClick = { showDatePicker = true }) { Text(text = "To $periodEnd") } if(showDatePicker) { DatePickerDialog( onDismissRequest = { showDatePicker = false }, confirmButton = { TextButton( onClick = { showDatePicker = false // 从state中获取选中的日期并转换为LocalDateTime dateRangePickerState.selectedStartDateMillis?.let { startMillis -> periodStart = LocalDateTime.ofInstant( java.time.Instant.ofEpochMilli(startMillis), ZoneId.systemDefault() ) } dateRangePickerState.selectedEndDateMillis?.let { endMillis -> periodEnd = LocalDateTime.ofInstant( java.time.Instant.ofEpochMilli(endMillis), ZoneId.systemDefault() ) } } ) { Text("Ok") } }, dismissButton = { TextButton(onClick = { showDatePicker = false }) { Text("Cancel") } } ) { DateRangePicker( state = dateRangePickerState, ) } } } } @Preview(showBackground = true) @Composable fun DatePickerTemplatePreview() { DatePickerTemplateTheme { DatePickerTemplate() } }
核心修改点说明
- 修正可变状态:将
periodEnd从val改为var,确保可以被重新赋值。 - 持久化DateRangePickerState:把
DateRangePickerState放到remember块中,避免每次重组都创建新状态,保证选中状态的连续性。 - 确认时更新变量:在确认按钮的点击事件中,从
dateRangePickerState取出选中的起始/结束日期毫秒数,转换为LocalDateTime后赋值给periodStart和periodEnd。 - 初始状态同步:初始化
DateRangePickerState时,将当前的periodStart和periodEnd转换为毫秒数,确保Picker初始显示与变量一致。
内容的提问来源于stack exchange,提问作者Alele
相关产品推荐
相关产品推荐

