तारीख चुनने वाले टूल

तारीख चुनने वाले टूल की मदद से, उपयोगकर्ता कोई तारीख, तारीख की सीमा या दोनों चुन सकते हैं. इनमें कैलेंडर डायलॉग या टेक्स्ट इनपुट का इस्तेमाल किया जाता है, ताकि उपयोगकर्ता तारीखें चुन सकें.

टाइप

तारीख चुनने वाले टूल तीन तरह के होते हैं:

  • डॉक किया गया: यह लेआउट में इनलाइन दिखता है. यह कॉम्पैक्ट लेआउट के लिए सही है, जहां डायलॉग बॉक्स का इस्तेमाल करने से उपयोगकर्ता को परेशानी हो सकती है.
  • मोडल: यह ऐप्लिकेशन के कॉन्टेंट के ऊपर, डायलॉग बॉक्स के तौर पर दिखता है. इससे तारीख चुनने पर ज़्यादा फ़ोकस किया जा सकता है.
  • मोडल इनपुट: इसमें टेक्स्ट फ़ील्ड के साथ-साथ, तारीख चुनने वाला मोडल टूल भी होता है.

इन कंपोज़ेबल का इस्तेमाल करके, अपने ऐप्लिकेशन में तारीख चुनने वाले टूल लागू किए जा सकते हैं:

  • DatePicker: तारीख चुनने वाले टूल के लिए सामान्य कंपोज़ेबल. इस्तेमाल किए जाने वाले कंटेनर से तय होता है कि वह डॉक किया गया है या मॉडल है.
  • DatePickerDialog: मोडल और मोडल इनपुट, दोनों तरह के तारीख चुनने वाले टूल के लिए कंटेनर.
  • DateRangePicker: तारीख चुनने वाले किसी भी टूल के लिए, जहां उपयोगकर्ता शुरू और खत्म होने की तारीख के साथ कोई रेंज चुन सकता है.

राज्य

तारीख चुनने वाले टूल के अलग-अलग कॉम्पोज़ेबल के बीच शेयर किया जाने वाला मुख्य पैरामीटर state है. यह DatePickerState या DateRangePickerState ऑब्जेक्ट लेता है. इनकी प्रॉपर्टी, तारीख चुनने वाले टूल का इस्तेमाल करके उपयोगकर्ता के चुने गए विकल्प की जानकारी कैप्चर करती हैं. जैसे, चुनी गई मौजूदा तारीख.

चुनी गई तारीख का इस्तेमाल करने के तरीके के बारे में ज़्यादा जानने के लिए, चुनी गई तारीख सेक्शन का इस्तेमाल करें देखें.

डॉक किया गया तारीख चुनने वाला टूल

यहां दिए गए उदाहरण में, एक टेक्स्ट फ़ील्ड है. इसमें उपयोगकर्ता को जन्म की तारीख डालने के लिए कहा गया है. फ़ील्ड में मौजूद कैलेंडर आइकॉन पर क्लिक करने से, इनपुट फ़ील्ड के नीचे तारीख चुनने वाला टूल खुलता है.

@Composable
fun DatePickerDocked() {
    var showDatePicker by remember { mutableStateOf(false) }
    val datePickerState = rememberDatePickerState()
    val selectedDate = datePickerState.selectedDateMillis?.let {
        convertMillisToDate(it)
    } ?: ""

    Box(
        modifier = Modifier.fillMaxWidth()
    ) {
        OutlinedTextField(
            value = selectedDate,
            onValueChange = { },
            label = { Text("DOB") },
            readOnly = true,
            trailingIcon = {
                IconButton(onClick = { showDatePicker = !showDatePicker }) {
                    Icon(
                        imageVector = Icons.Default.DateRange,
                        contentDescription = "Select date"
                    )
                }
            },
            modifier = Modifier
                .fillMaxWidth()
                .height(64.dp)
        )

        if (showDatePicker) {
            Popup(
                onDismissRequest = { showDatePicker = false },
                alignment = Alignment.TopStart
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .offset(y = 64.dp)
                        .shadow(elevation = 4.dp)
                        .background(MaterialTheme.colorScheme.surface)
                        .padding(16.dp)
                ) {
                    DatePicker(
                        state = datePickerState,
                        showModeToggle = false
                    )
                }
            }
        }
    }
}

@Composable
fun DatePickerFieldToModal(modifier: Modifier = Modifier) {
    var selectedDate by remember { mutableStateOf<Long?>(null) }
    var showModal by remember { mutableStateOf(false) }

    OutlinedTextField(
        value = selectedDate?.let { convertMillisToDate(it) } ?: "",
        onValueChange = { },
        label = { Text("DOB") },
        placeholder = { Text("MM/DD/YYYY") },
        trailingIcon = {
            Icon(Icons.Default.DateRange, contentDescription = "Select date")
        },
        modifier = modifier
            .fillMaxWidth()
            .pointerInput(selectedDate) {
                awaitEachGesture {
                    // Modifier.clickable doesn't work for text fields, so we use Modifier.pointerInput
                    // in the Initial pass to observe events before the text field consumes them
                    // in the Main pass.
                    awaitFirstDown(pass = PointerEventPass.Initial)
                    val upEvent = waitForUpOrCancellation(pass = PointerEventPass.Initial)
                    if (upEvent != null) {
                        showModal = true
                    }
                }
            }
    )

    if (showModal) {
        DatePickerModal(
            onDateSelected = { selectedDate = it },
            onDismiss = { showModal = false }
        )
    }
}

fun convertMillisToDate(millis: Long): String {
    val formatter = SimpleDateFormat("MM/dd/yyyy", Locale.getDefault())
    return formatter.format(Date(millis))
}

कोड के बारे में अहम बातें

  • जब उपयोगकर्ता IconButton पर क्लिक करता है, तो तारीख चुनने वाला टूल दिखता है.
    • आइकॉन बटन, OutlinedTextField के trailingIcon पैरामीटर के लिए आर्ग्युमेंट के तौर पर काम करता है.
    • showDatePicker स्टेट वैरिएबल, डॉक किए गए तारीख चुनने वाले टूल की विज़िबिलिटी को कंट्रोल करता है.
  • तारीख चुनने वाले टूल का कंटेनर, Popup कंपोज़ेबल है. यह अन्य एलिमेंट के लेआउट पर असर डाले बिना, कॉन्टेंट को ओवरले करता है.
  • selectedDate, DatePickerState ऑब्जेक्ट से चुनी गई तारीख की वैल्यू को कैप्चर करता है. साथ ही, convertMillisToDate फ़ंक्शन का इस्तेमाल करके उसे फ़ॉर्मैट करता है.
  • चुनी गई तारीख, टेक्स्ट फ़ील्ड में दिखती है.
  • डॉक किया गया तारीख चुनने वाला टूल, offset मॉडिफ़ायर का इस्तेमाल करके टेक्स्ट फ़ील्ड के नीचे रखा जाता है.
  • टेक्स्ट फ़ील्ड और तारीख चुनने वाले टूल की सही लेयरिंग के लिए, Box का इस्तेमाल रूट कंटेनर के तौर पर किया जाता है.

नतीजे

कैलेंडर आइकॉन पर क्लिक करने के बाद, यह इस तरह दिखता है:

डॉक किए गए तारीख चुनने वाले टूल का उदाहरण.
पहली इमेज. डॉक किया गया तारीख चुनने वाला टूल.

तारीख चुनने वाला मॉडल टूल, स्क्रीन पर फ़्लोट होने वाला डायलॉग दिखाता है. इसे लागू करने के लिए, DatePickerDialog बनाएं और उसे DatePicker पास करें.

@Composable
fun DatePickerModal(
    onDateSelected: (Long?) -> Unit,
    onDismiss: () -> Unit
) {
    val datePickerState = rememberDatePickerState()

    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = {
                onDateSelected(datePickerState.selectedDateMillis)
                onDismiss()
            }) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}

  • DatePickerModal ऐप्लिकेशन बनाने की सुविधा, तारीख चुनने वाला मॉडल टूल दिखाती है.
  • जब उपयोगकर्ता कोई तारीख चुनता है, तब onDateSelected लैम्डा एक्सप्रेशन काम करता है.
    • यह पैरंट कंपोज़ेबल को चुनी गई तारीख दिखाता है.
  • onDismiss लैम्डा एक्सप्रेशन तब लागू होता है, जब उपयोगकर्ता डायलॉग को खारिज करता है.

नतीजे

लागू होने पर यह इस तरह दिखता है:

तारीख चुनने वाले मॉडल टूल का उदाहरण.
दूसरी इमेज. तारीख चुनने वाला एक मॉडल टूल.

तारीख चुनने वाला टूल

इनपुट के साथ तारीख चुनने वाला मॉडल टूल, स्क्रीन पर फ़्लोट होने वाला डायलॉग दिखाता है. साथ ही, उपयोगकर्ता को तारीख डालने की अनुमति देता है.

@Composable
fun DatePickerModalInput(
    onDateSelected: (Long?) -> Unit,
    onDismiss: () -> Unit
) {
    val datePickerState = rememberDatePickerState(initialDisplayMode = DisplayMode.Input)

    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(onClick = {
                onDateSelected(datePickerState.selectedDateMillis)
                onDismiss()
            }) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DatePicker(state = datePickerState)
    }
}

यह मोडल तारीख चुनने वाला टूल के उदाहरण से काफ़ी मिलता-जुलता है. इनमें मुख्य अंतर यह है:

  • initialDisplayMode पैरामीटर, शुरुआती डिसप्ले मोड को DisplayMode.Input पर सेट करता है.
इनपुट के साथ तारीख चुनने वाला मॉडल टूल.
तीसरी इमेज. इनपुट के साथ तारीख चुनने वाला टूल.

तारीख चुनने वाला टूल जिसमें सीमा हो

तारीख चुनने वाला ऐसा टूल बनाया जा सकता है जिससे उपयोगकर्ता, शुरू और खत्म होने की तारीख के बीच की कोई सीमा चुन सके. इसके लिए, DateRangePicker का इस्तेमाल करें.

DateRangePicker का इस्तेमाल, DatePicker के इस्तेमाल जैसा ही है. इसका इस्तेमाल PopUp के चाइल्ड के तौर पर, डॉक किए गए पिकर के लिए किया जा सकता है. इसके अलावा, इसका इस्तेमाल मॉडल पिकर के तौर पर किया जा सकता है और इसे DatePickerDialog को पास किया जा सकता है. इनमें मुख्य अंतर यह है कि DatePickerState के बजाय, DateRangePickerState का इस्तेमाल किया जाता है.

यहां दिए गए स्निपेट में, रेंज के साथ मॉडल तारीख चुनने वाला टूल बनाने का तरीका बताया गया है:

@Composable
fun DateRangePickerModal(
    onDateRangeSelected: (Pair<Long?, Long?>) -> Unit,
    onDismiss: () -> Unit
) {
    val dateRangePickerState = rememberDateRangePickerState()

    DatePickerDialog(
        onDismissRequest = onDismiss,
        confirmButton = {
            TextButton(
                onClick = {
                    onDateRangeSelected(
                        Pair(
                            dateRangePickerState.selectedStartDateMillis,
                            dateRangePickerState.selectedEndDateMillis
                        )
                    )
                    onDismiss()
                }
            ) {
                Text("OK")
            }
        },
        dismissButton = {
            TextButton(onClick = onDismiss) {
                Text("Cancel")
            }
        }
    ) {
        DateRangePicker(
            state = dateRangePickerState,
            title = {
                Text(
                    text = "Select date range"
                )
            },
            showModeToggle = false,
            modifier = Modifier
                .fillMaxWidth()
                .height(500.dp)
                .padding(16.dp)
        )
    }
}

कोड के बारे में अहम बातें

  • onDateRangeSelected पैरामीटर एक कॉलबैक है, जो Pair<Long?, Long?> को रिसीव करता है. यह चुनी गई शुरू और खत्म होने की तारीखों को दिखाता है. इससे पैरंट कंपोज़ेबल को चुनी गई रेंज का ऐक्सेस मिलता है.
  • rememberDateRangePickerState(), तारीख की सीमा चुनने वाले विजेट के लिए स्टेट बनाता है.
  • DatePickerDialog, एक मॉडल डायलॉग कंटेनर बनाता है.
  • पुष्टि करने वाले बटन के onClick हैंडलर में, onDateRangeSelected चुनी गई रेंज को पैरंट कंपोज़ेबल में पास करता है.
  • DateRangePicker कंपोज़ेबल, डायलॉग के कॉन्टेंट के तौर पर काम करता है.

नतीजे

लागू होने पर यह इस तरह दिखता है:

तारीख की सीमा चुनने वाले टूल का उदाहरण.
चौथी इमेज. चुनी गई तारीख की सीमा के साथ, तारीख चुनने वाला मॉडल टूल.

चुनी गई तारीख का इस्तेमाल करना

चुनी गई तारीख को कैप्चर करने के लिए, उसे पैरंट कंपोज़ेबल में Long के तौर पर ट्रैक करें और वैल्यू को onDateSelected में DatePicker को पास करें. यहां दिया गया स्निपेट इसे दिखाता है. हालांकि, स्निपेट के आधिकारिक ऐप्लिकेशन में, इसे पूरी तरह से लागू होते हुए देखा जा सकता है.

// ...
    var selectedDate by remember { mutableStateOf<Long?>(null) }
// ...
        if (selectedDate != null) {
            val date = Date(selectedDate!!)
            val formattedDate = SimpleDateFormat("MMM dd, yyyy", LocalLocale.current.platformLocale).format(date)
            Text("Selected date: $formattedDate")
        } else {
            Text("No date selected")
        }
// ...
        DatePickerModal(
            onDateSelected = {
                selectedDate = it
                showModal = false
            },
            onDismiss = { showModal = false }
        )
    }
// ...

तारीख की सीमा चुनने वाले टूल के लिए भी यही तरीका अपनाया जाता है. हालांकि, आपको शुरू और खत्म होने की वैल्यू कैप्चर करने के लिए, Pair<Long?, Long?> या डेटा क्लास का इस्तेमाल करना होगा.

इन्हें भी देखें