🌊
JetpackCompose DatePickerを使う方法
残念ながらJetpackComposeにはDatePickerがない......
なので前回と同じではありますがMaterialDatePickerを使ってしまいましょう。
サンプルコード
@Composable
fun MainScreen(){
var datePicked : String? by remember {
mutableStateOf(null)
}
val updatedDate = { date : Long? ->
datePicked = DateFormater(date)
}
Scaffold(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
) {
DatePickerview( datePicked, updatedDate )
}
}
@Composable
fun DatePickerview(
datePicked : String?,
updatedDate : ( date : Long? ) -> Unit,
) {
val activity = LocalContext.current as AppCompatActivity
fun showDatePicker(
activity: AppCompatActivity,
updatedDate: (Long?) -> Unit)
) {
val calendar: Calendar = Calendar.getInstance()
calendar.apply {
set(Calendar.YEAR, 1950)
set(Calendar.MONTH, 1)
set(Calendar.DAY_OF_MONTH, 1)
}
MaterialDatePicker.Builder.datePicker()
.setSelection(calendar.timeInMillis).build().apply {
show(activity.supportFragmentManager, "Tag")
addOnPositiveButtonClickListener {
validInputEntity.update {
updatedDate(it)
}
}
}
}
Box(
modifier = Modifier
.fillMaxSize()
.wrapContentSize(Alignment.TopStart)
.padding(top = 10.dp)
.border(0.5.dp, MaterialTheme.colors.onSurface.copy(alpha = 0.5f))
.clickable{
showDatePicker(activity, updatedDate)
}
) {
ConstraintLayout(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
val (lable, iconView) = createRefs()
Text(
text= datePicked?:"Date Picker",
color = MaterialTheme.colors.onSurface,
modifier = Modifier
.fillMaxWidth()
.constrainAs(lable) {
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(iconView.start)
width = Dimension.fillToConstraints
}
)
Icon(
imageVector = Icons.Default.DateRange,
contentDescription = null,
modifier = Modifier
.size(20.dp, 20.dp)
.constrainAs(iconView) {
end.linkTo(parent.end)
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
},
tint = MaterialTheme.colors.onSurface
)
}
}
}
fun dateFormater(milliseconds: Long): String {
milliseconds.let {
val formatter = SimpleDateFormat("yyyy/MM/dd", Locale.JAPANESE)
return formatter.format(milliseconds)
}
}
解説
側は何でもいいから適当に用意して、
onClickしたらMaterialDatePicker.Builder.datePicker()を
showするようにして表示している感じ。
しかしまた今回も色の変更ができない......
諦めてxmlいじってテーマ作ってスタイル作って
MaterialDatePicker用のカスタムスタイルを作りましょう。
kotlinで完結したいね......
色変更のサンプルコード
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AlertDialogTheme" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="buttonBarPositiveButtonStyle">@style/Positive.Button</item>
<item name="buttonBarNegativeButtonStyle">@style/Negative.Button</item>
</style>
<style name="Positive.Button" parent="Widget.MaterialComponents.Button.TextButton">
<item name="android:textColor">@color/blue</item>
<item name="android:textStyle">bold</item>
</style>
<style name="Negative.Button" parent="Widget.MaterialComponents.Button.TextButton">
<item name="android:textColor">@color/blue</item>
</style>
<!-- MaterialDatePicker のテーマ -->
<style name="MaterialCalendarTheme" parent="ThemeOverlay.MaterialComponents.MaterialCalendar">
<item name="materialCalendarStyle">@style/MyMaterialCalendar</item>
<item name="buttonBarPositiveButtonStyle">@style/Positive.Button</item>
<item name="buttonBarNegativeButtonStyle">@style/Negative.Button</item>
<item name="materialCalendarHeaderTitle">@style/MyMaterialCalendarHeaderTitle</item>
<item name="materialCalendarHeaderSelection">@style/MyMaterialCalendarHeaderSelection</item>
<item name="materialCalendarYearNavigationButton">@style/MyMaterialCalendarSelection</item>
<item name="materialCalendarMonthNavigationButton">@style/MyMaterialCalendarSelection</item>
<item name="materialCalendarHeaderToggleButton">@style/HeaderToggleButton</item>
<!-- 曜日や手入力テキスト色 -->
<item name="android:textColorPrimary">@color/black</item>
<!-- ヘッダーの背景色 -->
<item name="colorPrimary">@color/bland</item>
<!-- 日付の背景色 -->
<item name="colorSurface">@color/white</item>
<!-- 日付の年選択時の年の色 -->
<item name="colorOnSurface">@color/black</item>
<!-- ヘッダーのアイコン色 -->
<item name="colorOnPrimary">@color/white</item>
</style>
<!-- MaterialDatePicker のスタイル -->
<style name="MyMaterialCalendar" parent="Widget.MaterialComponents.MaterialCalendar">
<item name="dayStyle">@style/MyMaterialCalendarDay</item>
<item name="daySelectedStyle">@style/MyMaterialCalendarDaySelected</item>
</style>
<!-- MaterialDatePicker のヘッダータイトル -->
<style name="MyMaterialCalendarHeaderTitle" parent="Widget.MaterialComponents.MaterialCalendar.HeaderTitle">
<item name="android:textColor">@color/white</item>
</style>
<!-- MaterialDatePicker の選択されたヘッダータイトル -->
<style name="MyMaterialCalendarHeaderSelection" parent="Widget.MaterialComponents.MaterialCalendar.HeaderSelection">
<item name="android:textColor">@color/white</item>
</style>
<!-- MaterialDatePicker の年月選択ボタン -->
<style name="MyMaterialCalendarSelection" parent="Base.Widget.MaterialComponents.MaterialCalendar.NavigationButton">
<item name="android:textColor">@color/black</item>
</style>
<!-- MaterialDatePicker の日付 -->
<style name="MyMaterialCalendarDay" parent="Widget.MaterialComponents.MaterialCalendar.Day">
<item name="itemTextColor">@color/black</item>
</style>
<!-- MaterialDatePicker の選択された日 -->
<style name="MyMaterialCalendarDaySelected" parent="Widget.MaterialComponents.MaterialCalendar.Day.Selected">
<item name="itemFillColor">@color/bland</item>
<item name="itemTextColor">@color/white</item>
</style>
<!-- MaterialDatePicker の直接入力切り替えボタン -->
<style name="HeaderToggleButton" parent="@style/Widget.MaterialComponents.MaterialCalendar.HeaderToggleButton">
<!-- <item name="android:visibility">gone</item>-->
</style>
</resources>
参考記事
Discussion