তারিখ বাছাইকারী

তারিখ বাছাইকারীরা ব্যবহারকারীদের একটি তারিখ, একটি তারিখ ব্যাপ্তি বা উভয়ই নির্বাচন করতে দেয়৷ ব্যবহারকারীদের তারিখ নির্বাচন করতে দেওয়ার জন্য তারা একটি ক্যালেন্ডার ডায়ালগ বা পাঠ্য ইনপুট ব্যবহার করে।

প্রকারভেদ

তিন ধরনের খেজুর বাছাইকারী আছে:

  • ডকড : লেআউটের মধ্যে ইনলাইন দেখায়। এটি কমপ্যাক্ট লেআউটের জন্য উপযুক্ত যেখানে একটি ডেডিকেটেড ডায়ালগ অনুপ্রবেশকারী মনে হতে পারে।
  • মডেল : অ্যাপের বিষয়বস্তুকে ওভারলে করা একটি ডায়ালগ হিসাবে উপস্থিত হয়। এটি তারিখ নির্বাচনের উপর একটি স্পষ্ট ফোকাস প্রদান করে।
  • মোডাল ইনপুট : একটি মডেল ডেট পিকারের সাথে একটি পাঠ্য ক্ষেত্রকে একত্রিত করে।

আপনি নিম্নলিখিত কম্পোজেবলগুলি ব্যবহার করে আপনার অ্যাপে এই তারিখ বাছাইকারীদের প্রয়োগ করতে পারেন:

  • 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 রুট ধারক হিসাবে ব্যবহৃত হয়।

ফলাফল

ক্যালেন্ডার আইকনে ক্লিক করার পরে, এই বাস্তবায়নটি নিম্নরূপ প্রদর্শিত হবে:

ডক করা তারিখ পিকার উদাহরণ।
চিত্র 1. একটি ডক করা তারিখ পিকার।

একটি মডেল ডেট পিকার একটি ডায়ালগ প্রদর্শন করে যা স্ক্রিনের উপর ভাসছে। এটি বাস্তবায়ন করতে, একটি 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 lambda এক্সপ্রেশনটি কার্যকর হয়।
    • এটি নির্বাচিত তারিখটিকে প্যারেন্ট কম্পোজেবলের কাছে প্রকাশ করে।
  • ব্যবহারকারী ডায়ালগ খারিজ করলে onDismiss lambda এক্সপ্রেশনটি কার্যকর হয়।

ফলাফল

এই বাস্তবায়ন নিম্নলিখিত হিসাবে প্রদর্শিত হবে:

মডেল তারিখ চয়নকারী উদাহরণ.
চিত্র 2. একটি মডেল ডেট পিকার।

ইনপুট মডেল তারিখ পিকার

ইনপুট সহ একটি মডেল ডেট পিকার একটি ডায়ালগ প্রদর্শন করে যা স্ক্রিনের উপর ভাসমান এবং ব্যবহারকারীকে একটি তারিখ ইনপুট করার অনুমতি দেয়।

@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 এ সেট করে।
ইনপুট সহ মডেল তারিখ পিকার।
চিত্র 3. ইনপুট সহ একটি মডেল ডেট পিকার।

পরিসীমা সহ তারিখ পিকার

আপনি একটি তারিখ পিকার তৈরি করতে পারেন যা ব্যবহারকারীকে শুরু এবং শেষ তারিখের মধ্যে একটি পরিসর নির্বাচন করতে দেয়৷ এটি করতে, 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 কম্পোজেবল ডায়ালগ বিষয়বস্তু হিসাবে কাজ করে।

ফলাফল

এই বাস্তবায়ন নিম্নলিখিত হিসাবে প্রদর্শিত হবে:

মডেল পরিসীমা তারিখ চয়নকারী উদাহরণ.
চিত্র 4. একটি নির্বাচিত পরিসর সহ একটি মডেল তারিখ চয়নকারী৷

নির্বাচিত তারিখ ব্যবহার করুন

নির্বাচিত তারিখটি ক্যাপচার করতে, এটিকে প্যারেন্ট কম্পোজেবলে Long হিসাবে ট্র্যাক করুন এবং onDateSelectedDatePicker কাছে মানটি পাস করুন। নীচের স্নিপেটটি এটি প্রদর্শন করে, যদিও আপনি অফিসিয়াল স্নিপেট অ্যাপে সম্পূর্ণ বাস্তবায়ন দেখতে পারেন।

// ...
    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?> বা একটি ডেটা ক্লাস ব্যবহার করতে হবে।

এছাড়াও দেখুন