日付選択ツールを使用すると、ユーザーは日付、日付の範囲、またはその両方を選択できます。カレンダー ダイアログまたはテキスト入力を使用して、ユーザーが日付を選択できるようにします。
型
日付選択ツールには次の 3 種類があります。
- ドッキング: レイアウト内にインラインで表示されます。これは、専用のダイアログが煩わしく感じる可能性があるコンパクト レイアウトに適しています。
- モーダル: アプリのコンテンツにオーバーレイするダイアログとして表示されます。これにより、日付選択に明確な焦点が提供されます。
- モーダル入力: テキスト フィールドとモーダル日付選択ツールを組み合わせたものです。
これらの日付選択ツールは、次のコンポーザブルを使用してアプリに実装できます。
DatePicker
: 日付選択ツールの一般的なコンポーザブル。ドッキングまたはモデルのどちらであるかは、使用するコンテナによって決まります。DatePickerDialog
: モーダルとモーダル入力日付選択ツールの両方のコンテナ。DateRangePicker
: ユーザーが開始日と終了日を含む期間を選択できる日付選択ツール。
状態
さまざまな日付選択ツールのコンポーザブルで共通するキー パラメータは state
です。これは、DatePickerState
オブジェクトまたは DateRangePickerState
オブジェクトを受け取ります。これらのプロパティは、現在選択されている日付など、日付選択ツールを使用するユーザーの選択に関する情報を取得します。
選択した日付の使用方法について詳しくは、選択した日付を使用するをご覧ください。
固定された日付選択ツール
次の例では、生年月日の入力を求めるテキスト フィールドがあります。フィールドのカレンダー アイコンをクリックすると、入力フィールドの下にドッキングされた日付選択ツールが開きます。
@Composable fun DatePickerDocked() { var showDatePicker by remember { mutableStateOf(false) } val datePickerState = rememberDatePickerState() val selectedDate = datePickerState.selectedDateMillis?.let { convertMillisToDate(it) } ?: "" Box( modifier = Modifier.fillMaxWidth() ) { OutlinedTextField( value = selectedDate, onValueChange = { }, label = { Text("DOB") }, readOnly = true, trailingIcon = { IconButton(onClick = { showDatePicker = !showDatePicker }) { Icon( imageVector = Icons.Default.DateRange, contentDescription = "Select date" ) } }, modifier = Modifier .fillMaxWidth() .height(64.dp) ) if (showDatePicker) { Popup( onDismissRequest = { showDatePicker = false }, alignment = Alignment.TopStart ) { Box( modifier = Modifier .fillMaxWidth() .offset(y = 64.dp) .shadow(elevation = 4.dp) .background(MaterialTheme.colorScheme.surface) .padding(16.dp) ) { DatePicker( state = datePickerState, showModeToggle = false ) } } } } } @Composable fun DatePickerFieldToModal(modifier: Modifier = Modifier) { var selectedDate by remember { mutableStateOf<Long?>(null) } var showModal by remember { mutableStateOf(false) } OutlinedTextField( value = selectedDate?.let { convertMillisToDate(it) } ?: "", onValueChange = { }, label = { Text("DOB") }, placeholder = { Text("MM/DD/YYYY") }, trailingIcon = { Icon(Icons.Default.DateRange, contentDescription = "Select date") }, modifier = modifier .fillMaxWidth() .pointerInput(selectedDate) { awaitEachGesture { // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput // in the Initial pass to observe events before the text field consumes them // in the Main pass. awaitFirstDown(pass = PointerEventPass.Initial) val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial) if (upEvent != null) { showModal = true } } } ) if (showModal) { DatePickerModal( onDateSelected = { selectedDate = it }, onDismiss = { showModal = false } ) } } fun convertMillisToDate(millis: Long): String { val formatter = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault()) return formatter.format(Date(millis)) }
コードに関する主なポイント
- ユーザーが
IconButton
をクリックすると、日付選択ツールが表示されます。- アイコンボタンは、
OutlinedTextField
のtrailingIcon
パラメータの引数として機能します。 showDatePicker
状態変数は、ドッキングされた日付選択ツールの表示を制御します。
- アイコンボタンは、
- 日付選択ツールのコンテナは
Popup
コンポーザブルであり、他の要素のレイアウトに影響を与えることなくコンテンツをオーバーレイします。 selectedDate
は、選択した日付の値をDatePickerState
オブジェクトから取得し、convertMillisToDate
関数を使用して形式設定します。- 選択した日付がテキスト フィールドに表示されます。
- ドッキング日付選択ツールは、
offset
修飾子を使用してテキスト フィールドの下に表示されます。 Box
は、テキスト フィールドと日付選択ツールを適切に階層化できるようにするために、ルートコンテナとして使用されます。
結果
カレンダー アイコンをクリックすると、実装は次のように表示されます。
モーダル日付選択ツール
モーダル日付選択ツールは、画面上にフローティング表示されるダイアログを表示します。実装するには、DatePickerDialog
を作成し、DatePicker
を渡します。
@Composable fun DatePickerModal( onDateSelected: (Long?) -> Unit, onDismiss: () -> Unit ) { val datePickerState = rememberDatePickerState() DatePickerDialog( onDismissRequest = onDismiss, confirmButton = { TextButton(onClick = { onDateSelected(datePickerState.selectedDateMillis) onDismiss() }) { Text("OK") } }, dismissButton = { TextButton(onClick = onDismiss) { Text("Cancel") } } ) { DatePicker(state = datePickerState) } }
コードに関する主なポイント
- コンポーズ可能な関数
DatePickerModal
は、モーダル日付選択ツールを表示します。 onDateSelected
ラムダ式は、ユーザーが日付を選択すると実行されます。- 選択した日付を親コンポーザブルに公開します。
onDismiss
ラムダ式は、ユーザーがダイアログを閉じると実行されます。
結果
これを実装すると次のようになります。
入力モーダルの日付選択ツール
入力付きのモーダル日付選択ツールでは、画面上にフローティング ダイアログが表示され、ユーザーが日付を入力できます。
@Composable fun DatePickerModalInput( onDateSelected: (Long?) -> Unit, onDismiss: () -> Unit ) { val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Input) DatePickerDialog( onDismissRequest = onDismiss, confirmButton = { TextButton(onClick = { onDateSelected(datePickerState.selectedDateMillis) onDismiss() }) { Text("OK") } }, dismissButton = { TextButton(onClick = onDismiss) { Text("Cancel") } } ) { DatePicker(state = datePickerState) } }
コードに関する主なポイント
これは、モーダル 日付選択ツールの例とほぼ同じです。主な違いは次のとおりです。
initialDisplayMode
パラメータは、最初の表示モードをDisplayMode.Input
に設定します。
期間選択ツール
開始日と終了日の間にある期間を選択できるように、日付選択ツールを作成できます。その場合は、DateRangePicker
を使用します。
DateRangePicker
の使用方法は DatePicker
と基本的に同じです。これは、PopUp
の子としてドッキングされた選択ツールに使用することも、モーダル選択ツールとして使用して DatePickerDialog
に渡すこともできます。主な違いは、DatePickerState
ではなく DateRangePickerState
を使用する点です。
次のスニペットは、範囲を指定してモーダル日付選択ツールを作成する方法を示しています。
@Composable fun DateRangePickerModal( onDateRangeSelected: (Pair<Long?, Long?>) -> Unit, onDismiss: () -> Unit ) { val dateRangePickerState = rememberDateRangePickerState() DatePickerDialog( onDismissRequest = onDismiss, confirmButton = { TextButton( onClick = { onDateRangeSelected( Pair( dateRangePickerState.selectedStartDateMillis, dateRangePickerState.selectedEndDateMillis ) ) onDismiss() } ) { Text("OK") } }, dismissButton = { TextButton(onClick = onDismiss) { Text("Cancel") } } ) { DateRangePicker( state = dateRangePickerState, title = { Text( text = "Select date range" ) }, showModeToggle = false, modifier = Modifier .fillMaxWidth() .height(500.dp) .padding(16.dp) ) } }
コードに関する主なポイント
onDateRangeSelected
パラメータは、選択した開始日と終了日を表すPair<Long?, Long?>
を受け取るコールバックです。これにより、親コンポーザブルは選択した範囲にアクセスできるようになります。rememberDateRangePickerState()
は、期間選択ツールの状態を作成します。DatePickerDialog
はモーダル ダイアログ コンテナを作成します。- 確認ボタンの
onClick
ハンドラで、onDateRangeSelected
は選択した範囲を親コンポーザブルに渡します。 DateRangePicker
コンポーザブルはダイアログ コンテンツとして機能します。
結果
これを実装すると次のようになります。
選択した日付を使用
選択した日付をキャプチャするには、親コンポーザブルで Long
として追跡し、値を onDateSelected
の DatePicker
に渡します。次のスニペットはこれを示していますが、完全な実装は公式スニペット アプリで確認できます。
// ... var selectedDate by remember { mutableStateOf<Long?>(null) } // ... 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") } // ... DatePickerModal( onDateSelected = { selectedDate = it showModal = false }, onDismiss = { showModal = false } ) } // ...
範囲の日付選択ツールにも基本的に同じことが適用されますが、開始日と終了日を取得するには Pair<Long?, Long?>
またはデータクラスを使用する必要があります。