tasjapr
tasjapr

Reputation: 1240

Material3 DatePicker background color in compose

I use DatePicker from material3 with custom colors.

I want to change background color of DatePicker. As I understand I need to change actually the elevation overlay color of Surface. But how I can do it?

Here is my code:

@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
@Composable
fun DatePickerPreview() {
    val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Picker)
    Surface(
        tonalElevation = 6.dp,
        contentColor = AppTheme.colors.textSecondary,
        modifier = Modifier.padding(16.dp),
        shape = MaterialTheme.shapes.extraLarge,
        ) {
        DatePicker(
            state = datePickerState,
            colors = AppDefaults.datePickerColors(),
            dateValidator = {
                DateTimeUtils.timestampToDate(it)?.isAfter(Date()) == false
            }
        )
    }
}

But background color of DatePicker now is the default material neutral color. I want to set my custom blue color for it instead of material purple, but with correctly calculated alpha like in material3. Explanation of material3 tonalElevation.

The overlay color comes from the primary color slot but I don't use MeterialTheme for my app, instead of this I use the my custom theme

And here is the result: enter image description here

Upvotes: 1

Views: 3011

Answers (2)

Sergei S
Sergei S

Reputation: 3077

We can use this approach with the material3 version 1.3.0

colors = DatePickerDefaults.colors(containerColor = Color.Green)

The full example. I added green and red colors to see the difference better

@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun CustomDatePickerDialog(
    date: LocalDate? = null,
    onDateSelected: (LocalDate) -> Unit,
    onDismiss: () -> Unit,
) {
    val datePickerState = rememberDatePickerState(date?.toMilliseconds())

    DatePickerDialog(
        onDismissRequest = { onDismiss() },
        colors = DatePickerDefaults.colors(
            containerColor = Color.Red,
        ),
        confirmButton = {
            Button(onClick = {
                datePickerState.selectedDateMillis?.let {
                    onDateSelected(it.toLocalDate())
                }
                onDismiss()
            }

            ) {
                Text(text = stringResource(SharedRes.strings.ok.resourceId))
            }
        },
        dismissButton = {
            Button(onClick = {
                onDismiss()
            }) {
                Text(text = stringResource(SharedRes.strings.cancel.resourceId))
            }
        }
    ) {
        DatePicker(
            state = datePickerState,
            colors = DatePickerDefaults.colors(
                containerColor = Color.Green,
            )
        )
    }
}

Image enter image description here

Upvotes: 1

tasjapr
tasjapr

Reputation: 1240

So, I solved this by locally using of MaterialTheme from material3 and overriding some colors:

@OptIn(ExperimentalMaterial3Api::class)
@Preview(showBackground = true, backgroundColor = 0xFFFFFFFF)
@Composable
fun DatePickerMaterialTheme() {
    val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Picker)
    val validate: (Long) -> Boolean = remember { { DateTimeUtils.timestampToDate(it)?.isAfter(Date()) == false } }

    MaterialTheme(
        colorScheme = MaterialTheme.colorScheme.copy(
            surface = AppTheme.colors.surface,
            primary = AppTheme.colors.primary,
            onPrimary = AppTheme.colors.onPrimary
        )
    ) {
        Surface(
            tonalElevation = 6.dp,
            shape = MaterialTheme.shapes.extraLarge
        ) {
            DatePicker(
                state = datePickerState,
                dateValidator = validate
            )
        }
    }
}

Upvotes: 4

Related Questions