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

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

প্রকারভেদ

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

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

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

  • 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 হিসাবে প্যারেন্ট কম্পোজেবলে ট্র্যাক করুন এবং 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?> অথবা একটি ডেটা ক্লাস ব্যবহার করতে হবে।

আরো দেখুন