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

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

प्रकार

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

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

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

  • 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", Locale.getDefault()).format(date)
            Text("Selected date: $formattedDate")
        } else {
            Text("No date selected")
        }
// ...
        DatePickerModal(
            onDateSelected = {
                selectedDate = it
                showModal = false
            },
            onDismiss = { showModal = false }
        )
    }
// ...

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

यह भी देखें: