5
0

Material3のDatePicker, TimePickerの仕様について

Posted at

はじめに

JetpackCompose個人開発でDatePickerやTimePickerを使った時に迷ったりつまづいたりした部分をまとめます。

DatePicker, TimePickerとは

MaterialDesign3で提供されている、日時を取得するUIコンポーネントです。
DatePicker
TimePicker

DatePicker

実装方法

build.gradleにimplementation("androidx.compose.material3:material3:$m3-version"
を追加して、Composable関数に@OptIn(ExperimentalMaterial3Api::class)などのアノテーションを使用することで組み込むことができます。

サンプルコード

先ほどのリンク先にあるDataPickerのサンプルコードです。

datePicker.kt
//... import

Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
    // Pre-select a date for January 4, 2020
    val datePickerState = rememberDatePickerState(initialSelectedDateMillis = 1578096000000)
    DatePicker(state = datePickerState, modifier = Modifier.padding(16.dp))

    Text("Selected date timestamp: ${datePickerState.selectedDateMillis ?: "no selection"}")
}

datePickerの実装にはDatePickerState型の引数が必要であることがわかります。また、datePickerStateの変数宣言では初期値を定義されており、どのような形でデータが保持されているのかもわかります。その下のTextから、値はdatePickerState.selectedDateMillisに保持されているということもわかりました。

DatePickerのデーターを保存する

データを取得したら保持したいですよね。実は、導入する部分についてはまとめられていましたが、そこからどう値を保持すればいいのか分からず、kotloinの実装に慣れていない私は苦戦しました。

結論、DatePickerに引数で渡したdatePickerStateに対して変更が行われるため、引数のdataPickerStateを参照すればいいです。変更が行われたかどうかについてはDatePickerDialogと組み合わせると簡単に管理できます。

上記のコード同様、DatePickerのドキュメントにあるサンプルコードの抜粋です。

DatePickerDialog.kt
// ...
    DatePickerDialog(
        // Dialogの外側を触ったときの挙動
        onDismissRequest = {
            openDialog.value = false
        },
        // OKボタン
        confirmButton = {
            TextButton(
                // OKボタンを押したときの挙動
                onClick = {
                    openDialog.value = false
                    // ...
                },
                enabled = confirmEnabled.value
            ) {
                Text("OK")
            }
        },
        // Cancelボタン
        dismissButton = {
            TextButton(
                onClick = {
                    // Cancelボタンを押したときの挙動
                    openDialog.value = false
                }
            ) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }

DatePickerDialogの引数に、各ボタンを押したとき実行する処理を入れられるので、データ保持などをしたいのであればOKの時のonClickの処理でデータ保持の関数を呼び出してあげるとうまくいきそうですね。保持するデータは先ほど確認した通り、datePickerState.selectedDateMillisで取り出せるのでこちらを渡せばうまくいくはずです。

TimePicker

サンプルコード

TimePickerのサンプルコードの抜粋です。

TimePicker.kt
// ...
TimePickerDialog(
    onCancel = { showTimePicker = false },
    onConfirm = {
        val cal = Calendar.getInstance()
        cal.set(Calendar.HOUR_OF_DAY, state.hour)
        cal.set(Calendar.MINUTE, state.minute)
        cal.isLenient = false
        snackScope.launch {
            snackState.showSnackbar("Entered time: ${formatter.format(cal.time)}")
        }
        showTimePicker = false
    },
) {
    TimePicker(state = state)
}

TimePickerをDatePicker同様に実装しようとしたら、DatePickerDialogのようなUIコンポーネントが提供されていないことがわかりました。調べて該当するサンプルコードを見つけることができました。

このリンクから引用して実装すると、TimePickerのドキュメントにある画像と同様のUIコンポーネントを実装できました。

TimePickerのデーターを保存する

DatePicker同様、TimePickerにrememberTimePickerState()を使用して定義した値state: TimePickerStateを引数で渡して、変更がこの引数に対して行われます。取り出す際はstate.hourstate.minuteとすれば値を返してくれます。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0