DatePicker (date selection) of Jetpack Compose Material3 component

foreword

When I used Comose to write APP before, the official solution for DatePicker has not been given yet.

At that time, in order to implement DatePicker in Compose, there were roughly two options:

One is to use the DatePicker of the original VIew, but because I feel that I have used Compose, and then use VIew, it always feels weird, so I didn't use this solution.

The second is to use a third-party DatePicker written by others. This is the solution I used at the time.

But after searching around, I only found a relatively easy-to-use library. However, this library is written by a French person, so the support for Chinese is not very good. As for this is not very good, what does it mean? You can see it by looking at the picture:

1.jpg

Hahaha, the abbreviation of the week is "star".

Regarding this problem, I also mentioned ISSUE, and explained the source of the problem and the solution in detail, but the author ignored me and has not fixed the problem until today.

As for why I don't mention PR after I fix it myself, see one of the replies:

I’m thinking about ability to inject the functionality from outside if necessary. Default function would be getDisplayName() but it can be overriden by the code similar to the one here. It’s obviously a bug in the Android implementation, so it shouldn’t be fixed by this library.

So the question is put on hold.

Until recently, when I looked through the Compose update log, I found that Compose Material3 1.1.0starting from the version, three new components have been added DatePicker DateRangePicker DatePickerDialog.

Finally, the official release date has been chosen, so I have to learn from it.

basic usage

First, is the most basic DatePickerusage.

DatePickerThere is only one required parameter state, which is used to set some configuration information and get the currently selected date.

We can rememberDatePickerStategenerate DatePickerwhat we need by state:

Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
    
    
    val datePickerState = rememberDatePickerState()
    DatePicker(state = datePickerState, modifier = Modifier.padding(16.dp))

    Text("当前选中日期的时间戳 ${
      
      datePickerState.selectedDateMillis ?: "没有选择"}")
}

The effect is as follows:

2.png

In this selection page, it is supported to switch to manual input mode by clicking the edit icon next to the date:

3.png
Of course, we can also rememberDatePickerStatespecify whether to initialize the date selection interface or the input box interface by setting the parameters:

val datePickerState = rememberDatePickerState(
    initialDisplayMode = DisplayMode.Picker // 默认显示选择框
    // initialDisplayMode = DisplayMode.Input // 默认显示输入框
)

In addition, we can also set the month displayed by default and the year that can only be selected:

val datePickerState = rememberDatePickerState(
    yearRange = 2023..2024,
    initialDisplayedMonthMillis = 1685577600000 // 注意这里是时间戳
)

If you want to limit the dates that can be selected more freely, you need to use Compose Material3 1.2.0-alpha02and above versions.

In this version, a parameter called is provided selectableDates, in which you can completely customize the dates that can be selected. Here is an example of the official sample. If we want to restrict the selection of weekends and only select dates after 2023, then we can do this Write:

val datePickerState = rememberDatePickerState(
        selectableDates = object : SelectableDates {
    
    
            // 禁止选择周末(周六和周日)
            override fun isSelectableDate(utcTimeMillis: Long): Boolean {
    
    
                return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    
    
                    val dayOfWeek = Instant.ofEpochMilli(utcTimeMillis).atZone(ZoneId.of("UTC"))
                        .toLocalDate().dayOfWeek
                    dayOfWeek != DayOfWeek.SUNDAY && dayOfWeek != DayOfWeek.SATURDAY
                } else {
    
    
                    val calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
                    calendar.timeInMillis = utcTimeMillis
                    calendar[Calendar.DAY_OF_WEEK] != Calendar.SUNDAY &&
                            calendar[Calendar.DAY_OF_WEEK] != Calendar.SATURDAY
                }
            }

            // 只允许选择2023年以前
            override fun isSelectableYear(year: Int): Boolean {
    
    
                return year > 2022
            }
        }
    )

The running effect is as follows:

4.png

You can see that weekends are grayed out and cannot be selected.

When clicking to select a year, you cannot choose before 2023:

5.png

In the dialog use

The above section is only about basic use, but in the actual development process, there may be more scenarios for selecting dates in Dialog.

So the official also provides a DatePickerDialogcomponent.

In fact, DatePickerDialogyou can see from the source code that it is simply encapsulated AlertDialog:

6.png

So in fact, there is basically no difference between using and DatePicker, except that the status of the dialog needs to be additionally processed. Here is still the official sample as an example:

val openDialog = remember {
    
     mutableStateOf(true) }
if (openDialog.value) {
    
    
    val datePickerState = rememberDatePickerState()
    val confirmEnabled = derivedStateOf {
    
     datePickerState.selectedDateMillis != null }
    DatePickerDialog(
        onDismissRequest = {
    
    
            openDialog.value = false
        },
        confirmButton = {
    
    
            TextButton(
                onClick = {
    
    
                    openDialog.value = false
                    println("选中时间戳为: ${
      
      datePickerState.selectedDateMillis}")
                },
                enabled = confirmEnabled.value
            ) {
    
    
                Text("确定")
            }
        },
        dismissButton = {
    
    
            TextButton(
                onClick = {
    
    
                    openDialog.value = false
                }
            ) {
    
    
                Text("取消")
            }
        }
    ) {
    
    
        DatePicker(state = datePickerState)
    }
}

The running effect is as follows:

7.png

date range selection

In addition, a function that can select a date range is also provided in the new MD3 API DateRangePicker.

Its parameters are DatePickersimilar to , except statechanged to DateRangePickerState.

We can rememberDateRangePickerStategenerate one via state.

In state, we can set the initial display mode of the time picker ( initialDisplayMode), the default start date ( initialSelectedStartDateMillis), the default end date ( initialSelectedEndDateMillis), the default display date ( initialDisplayedMonthMillis), and the year allowed to be selected ( yearRange).

And, likewise, Compose Material3 1.2.0-alpha02fully customizable dates can be selected on and above selectableDates.

The display effect of this function is as follows:

val state = rememberDateRangePickerState()
DateRangePicker(state = state, modifier = Modifier.fillMaxSize())

8.png

Get the selected value is still through sate:

println("选择的时间戳范围: ${
      
      state.selectedStartDateMillis}..${
      
      state.selectedEndDateMillis}")

Summarize

This article only briefly introduces the basic usage of date selection in Compsoe Material3, and more usage methods need to be explored by readers themselves.

It can be seen that there are more and more official components of Compose, and they are becoming more and more mature.

Compared with the state when the official version was just released, there was nothing and everything needed to be made by yourself, now it has almost covered all kinds of controls and requirements that we commonly use in development.

Guess you like

Origin blog.csdn.net/sinat_17133389/article/details/131293568