Implementing Material Design 3 Date Picker in Android Compose
Objective
Implement Material Design 3 DatePickerDialog()
& DatePicker()
in an Android Compose app, to display the selected date as a formatted string.
Environment
- Android Studio Iguana | 2023.2.1
- Compose version:
composeBom = "2023.08.00"
- Pixel 6 API 30 Emulator
- Project Minimum SDK: 27
Implementation
// Your package
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.DatePicker
import androidx.compose.material3.DatePickerDefaults
import androidx.compose.material3.DatePickerDialog
import androidx.compose.material3.DisplayMode
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
@OptIn(ExperimentalMaterial3Api::class)
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// Initial state setup for the DatePickerDialog. Specifies to show the picker initially
val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Picker)
// State to hold the selected date as a String
val selectedDateLabel = remember { mutableStateOf("") }
// State to control the visibility of the DatePickerDialog
val openDialog = remember { mutableStateOf(false) }
// Define the main color for the calendar picker
val calendarPickerMainColor = Color(0xFF722276)
// Layout for displaying the button and the selected date
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
// Button to open the DatePickerDialog
Button(
onClick = {
openDialog.value = !openDialog.value
}
) {
Text("Open Date Picker")
}
// Displays the selected date
Text("Selected Date: ${selectedDateLabel.value}")
}
// Conditional display of the DatePickerDialog based on the openDialog state
if (openDialog.value) {
// DatePickerDialog component with custom colors and button behaviors
DatePickerDialog(
colors = DatePickerDefaults.colors(
containerColor = Color(0xFFF5F0FF),
),
onDismissRequest = {
// Action when the dialog is dismissed without selecting a date
openDialog.value = false
},
confirmButton = {
// Confirm button with custom action and styling
TextButton(
onClick = {
// Action to set the selected date and close the dialog
openDialog.value = false
selectedDateLabel.value =
datePickerState.selectedDateMillis?.convertMillisToDate() ?: ""
}
) {
Text("OK", color = calendarPickerMainColor)
}
},
dismissButton = {
// Dismiss button to close the dialog without selecting a date
TextButton(
onClick = {
openDialog.value = false
}
) {
Text("CANCEL", color = calendarPickerMainColor)
}
}
) {
// The actual DatePicker component within the dialog
DatePicker(
state = datePickerState,
colors = DatePickerDefaults.colors(
selectedDayContainerColor = calendarPickerMainColor,
selectedDayContentColor = Color.White,
selectedYearContainerColor = calendarPickerMainColor,
selectedYearContentColor = Color.White,
todayContentColor = calendarPickerMainColor,
todayDateBorderColor = calendarPickerMainColor
)
)
}
}
}
}
}
fun Long.convertMillisToDate(): String {
// Create a calendar instance in the default time zone
val calendar = Calendar.getInstance().apply {
timeInMillis = this@convertMillisToDate
// Adjust for the time zone offset to get the correct local date
val zoneOffset = get(Calendar.ZONE_OFFSET)
val dstOffset = get(Calendar.DST_OFFSET)
add(Calendar.MILLISECOND, -(zoneOffset + dstOffset))
}
// Format the calendar time in the specified format
val sdf = SimpleDateFormat("MMM dd, yyyy", Locale.US)
return sdf.format(calendar.time)
}
Result
More Resources
For developers eager to deepen their understanding or explore more about modern Android development, a wealth of resources and guides await.
Your thoughts and involvement are truly priceless. If you’ve found this guide helpful, I’d love to hear from you. Consider sharing your support through claps or a follow, and stay tuned for more insights into the evolving landscape of Android development. See you in the next tutorial!
Deuk Services: Your Gateway to Leading Android Innovation
Are you looking to boost your business with top-tier Android solutions?Partner with Deuk services and take your projects to unparalleled heights.
🚀 Boost Your Productivity with Notion
New to Notion? Discover how it can revolutionize your productivity
Ready to take your productivity to the next level? Integrate this content into your Notion workspace with ease:
1 Access the Notion Version of this Content
2 Look for the Duplicate
button at the top-right corner of the page
3 Click on it to add this valuable resource to your Notion workspace
Seamlessly integrate this guide into your Notion workspace for easy access and swift reference. Leverage Notion AI to search and extract crucial insights, enhancing your productivity. Start curating your knowledge hub with Notion AI today and maximize every learning moment.