আইকন বোতাম

আইকন বোতাম ব্যবহারকারীরা যেসব অ্যাকশন নিতে পারেন সেগুলি দেখায়। আইকন বোতামে অবশ্যই একটি স্পষ্ট অর্থযুক্ত আইকন ব্যবহার করতে হবে এবং সাধারণত সাধারণ বা প্রায়ই ব্যবহৃত অ্যাকশনকে উপস্থাপন করতে হবে।

দু'ধরনের আইকন বোতাম আছে:

  • ডিফল্ট: এইসব বোতাম মেনু বা সার্চের মতো অন্যান্য এলিমেন্ট খুলতে পারে।
  • টগল করা যায়: এইসব বোতাম বাইনারি অ্যাকশনকে উপস্থাপন করতে পারে যা চালু বা বন্ধ করা যায়, যেমন "ফেভারিট" বা "বুকমার্ক"।
আলাদা আলাদা আইকন সহ ৫টি আইকন বোতাম (সেটিংস, আরও ইত্যাদি)। কিছু ফিল করা আছে, যা বেছে নেওয়া হয়েছে বলে ইঙ্গিত করে এবং কিছু আউটলাইন করা আছে।
ছবি ১. আইকন বোতাম, যার মধ্যে কিছু বোতাম ফিল করা আছে (যা বেছে নেওয়া হয়েছে তা বোঝায়) এবং আউটলাইন করা আছে।

API সারফেস

স্ট্যান্ডার্ড আইকন বোতাম প্রয়োগ করতে IconButton কম্পোজ করার উপযুক্ত আইটেম ব্যবহার করুন। ফিল্ড, ফিল্ড টোনাল বা আউটলাইন করা, এই ধরনের আলাদা আলাদা ভিজ্যুয়াল স্টাইল তৈরি করতে, যথাক্রমে FilledIconButton, FilledTonalIconButton এবং OutlinedIconButton ব্যবহার করুন।

IconButton-এর মূল প্যারামিটারগুলির মধ্যে এগুলি অন্তর্ভুক্ত:

  • onClick: ব্যবহারকারী আইকন বোতামে ট্যাপ করলে এক্সিকিউট হওয়া ল্যাম্বডা ফাংশন।
  • enabled: বোতামের চালু থাকার অবস্থাকে নিয়ন্ত্রণ করে এমন একটি বুলিয়ান। যখন false, বোতামটি ব্যবহারকারীর ইনপুটের উত্তর দেয় না।
  • content: বোতামের মধ্যে কম্পোজ করা যায় এমন কন্টেন্ট, সাধারণত একটি Icon।

প্রাথমিক উদাহরণ: টগল আইকন বোতাম

এই উদাহরণে টগল আইকন বোতাম কীভাবে প্রয়োগ করতে হয় তা দেখানো হয়েছে। টগল আইকন বোতামটি বেছে নেওয়া হয়েছে না হয়নি তার উপর ভিত্তি করে এর চেহারা পরিবর্তন করে।

@Preview
@Composable
fun ToggleIconButtonExample() {
    // isToggled initial value should be read from a view model or persistent storage.
    var isToggled by rememberSaveable { mutableStateOf(false) }

    IconButton(
        onClick = { isToggled = !isToggled }
    ) {
        Icon(
            painter = if (isToggled) painterResource(R.drawable.favorite_filled) else painterResource(R.drawable.favorite),
            contentDescription = if (isToggled) "Selected icon button" else "Unselected icon button."
        )
    }
}

কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট

  • ToggleIconButtonExample কম্পোজ করার উপযুক্ত আইটেম একটি টগল করা যায় এমন IconButton নির্ধারণ করে।
    • mutableStateOf(false) একটি MutableState অবজেক্ট তৈরি করে যা একটি বুলিয়ান ভ্যালু ধরে রাখে, প্রাথমিকভাবে false। এর ফলে isToggled একটি স্টেট হোল্ডার হয়ে যায়, অর্থাৎ, এর ভ্যালু পরিবর্তন হলেই Compose UI রিকম্পোজ করে।
    • rememberSaveable নিশ্চিত করে যে স্ক্রিন রোটেশনের মতো কনফিগারেশন পরিবর্তন জুড়ে isToggled স্টেট বজায় থাকে।
  • IconButton-এর onClick ল্যাম্বডা বোতামে ক্লিক করলে true ও false-এর মধ্যে স্টেট টগল করার মাধ্যমে বোতামের আচরণকে সংজ্ঞায়িত করে।
  • Icon কম্পোজ করার উপযুক্ত আইটেমের painter প্যারামিটার কন্ডিশনের উপর ভিত্তি করে একটি আলাদা painterResource লোড করে, যা isToggled স্ট্যাটাসের উপর নির্ভর করে। এর ফলে আইকনের ভিজ্যুয়াল চেহারা পরিবর্তন হয়ে যায়।
    • isToggled true হলে, এটি ভর্তি হার্টের ড্রয়েবল লোড করে।
    • isToggled-এর মান false হলে, এটি আউটলাইন করা হার্ট ড্রয়েবল লোড করে।
  • isToggled স্ট্যাটাসের উপর ভিত্তি করে Icon-এর contentDescription-ও আপডেট হয় যাতে অ্যাক্সেসিবিলিটি সংক্রান্ত উপযুক্ত তথ্য প্রদান করা যায়।

ফলাফল

নিচের ছবিতে আগের স্নিপেটের টগল আইকন বোতামটি বেছে না নেওয়া অবস্থায় দেখানো হয়েছে:

একটি প্রিয় টগল আইকন বোতাম (একটি হার্ট) যেটি বেছে নেওয়া হয়নি (ফাঁকা)।
ছবি ২. এর বেছে না নেওয়া অবস্থায় একটি "ফেভারিট" টগল আইকন বোতাম।

উন্নত উদাহরণ: প্রেস করার পরে রিপিট করা অ্যাকশন

এই বিভাগে কীভাবে আইকন বোতাম তৈরি করতে হয় তা দেখানো হয়েছে। ব্যবহারকারী বোতামটি প্রেস করে ধরে রাখলে, এটি ক্রমাগত অ্যাকশন ট্রিগার করে। প্রতি ক্লিকের জন্য একবার ট্রিগার করার পরিবর্তে এটি করা হয়।

@Composable
fun MomentaryIconButton(
    unselectedImage: Int,
    selectedImage: Int,
    contentDescription: String,
    modifier: Modifier = Modifier,
    stepDelay: Long = 100L, // Minimum value is 1L milliseconds.
    onClick: () -> Unit
) {
    val interactionSource = remember { MutableInteractionSource() }
    val isPressed by interactionSource.collectIsPressedAsState()
    val pressedListener by rememberUpdatedState(onClick)

    LaunchedEffect(isPressed) {
        while (isPressed) {
            delay(stepDelay.coerceIn(1L, Long.MAX_VALUE))
            pressedListener()
        }
    }

    IconButton(
        modifier = modifier,
        onClick = onClick,
        interactionSource = interactionSource
    ) {
        Icon(
            painter = if (isPressed) painterResource(id = selectedImage) else painterResource(id = unselectedImage),
            contentDescription = contentDescription,
        )
    }
}

কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট

  • MomentaryIconButton একটি unselectedImage: Int, বোতাম প্রেস করা না হলে আইকনের জন্য ড্রয়েবল রিসোর্স আইডি এবং selectedImage: Int, বোতাম প্রেস করা হলে আইকনের জন্য ড্রয়েবল রিসোর্স আইডি নেয়।
  • এটি ব্যবহারকারীর থেকে পাওয়া "প্রেস" ইন্টার‍্যাকশন ট্র্যাক করার জন্য interactionSource ব্যবহার করে।
  • বোতামটি অ্যাক্টিভভাবে প্রেস করা হলে isPressed-এর মান true হয় এবং অন্যথায় false হয়। isPressed true হলে, LaunchedEffect লুপে প্রবেশ করে।
    • এই লুপের মধ্যে, অ্যাকশন ট্রিগার করার মধ্যে পজ তৈরি করতে এটি delay (stepDelay সহ) ব্যবহার করে। coerceIn নিশ্চিত করে যে বিলম্ব কমপক্ষে ১ms যাতে অসীম লুপ এড়ানো যায়।
    • লুপের মধ্যে প্রতিটি বিলম্বের পরে pressedListener কল করা হয়। এর ফলে অ্যাকশনটি আবার করা হয়।
  • pressedListener rememberUpdatedState ব্যবহার করে এটি নিশ্চিত করে যে onClick ল্যাম্বডা (যে অ্যাকশন পারফর্ম করতে হবে) যেন সবসময় লেটেস্ট কম্পোজিশন থেকে সবচেয়ে আপ-টু-ডেট হয়।
  • বোতামটি বর্তমানে প্রেস করা আছে কিনা তার উপর ভিত্তি করে Icon আইকনটি এর ডিসপ্লে করা ছবি পরিবর্তন করে।
    • isPressed সত্যি হলে, selectedImage দেখানো হয়।
    • অন্যথায়, unselectedImage দেখানো হয়।

এরপরে, কোনও উদাহরণে এই MomentaryIconButton ব্যবহার করুন। নিম্নলিখিত স্নিপেট দুটি আইকন বোতামের মাধ্যমে একটি কাউন্টার কন্ট্রোল করার ডেমো দেখায়:

@Preview()
@Composable
fun MomentaryIconButtonExample() {
    var pressedCount by remember { mutableIntStateOf(0) }

    Row(
        modifier = Modifier.fillMaxWidth(),
        verticalAlignment = Alignment.CenterVertically
    ) {
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_rewind,
            selectedImage = R.drawable.fast_rewind_filled,
            stepDelay = 100L,
            onClick = { pressedCount -= 1 },
            contentDescription = "Decrease count button"
        )
        Spacer(modifier = Modifier)
        Text("advanced by $pressedCount frames")
        Spacer(modifier = Modifier)
        MomentaryIconButton(
            unselectedImage = R.drawable.fast_forward,
            selectedImage = R.drawable.fast_forward_filled,
            contentDescription = "Increase count button",
            stepDelay = 100L,
            onClick = { pressedCount += 1 }
        )
    }
}

কোড সম্পর্কে গুরুত্বপূর্ণ পয়েন্ট

  • MomentaryIconButtonExample কম্পোজ করার উপযুক্ত ডিসপ্লেতে দুটি MomentaryIconButton ইনস্ট্যান্স ও একটি Text কম্পোজ করার উপযুক্ত এলিমেন্ট আছে যা কাউন্টার বাড়ানো ও কমানোর জন্য UI তৈরি করে।Row
  • এটি remember ও mutableIntStateOf ব্যবহার করে একটি pressedCount পরিবর্তনযোগ্য স্টেট ভেরিয়েবল বজায় রাখে, যা ০ হিসেবে ইনিশিয়ালাইজ করা হয়। pressedCount পরিবর্তন হলে, এটি লক্ষ্য করা যেকোনও কম্পোজ করার উপযুক্ত আইটেম (যেমন Text কম্পোজ করার উপযুক্ত আইটেম) নতুন ভ্যালু দেখানোর জন্য আবার কম্পোজ করা হয়।
  • ক্লিক করা বা ধরে রাখলে প্রথম MomentaryIconButton কমে যায় pressedCount।
  • ক্লিক করা হলে বা হোল্ড করে রাখলে দ্বিতীয় MomentaryIconButton বেড়ে যায় pressedCount।
  • দুটি বোতামই ১০০ মিলিসেকেন্ডের stepDelay ব্যবহার করে, এর অর্থ হল কোনও বোতাম হোল্ড করে রাখলে onClick অ্যাকশন প্রতি ১০০ মিলিসেকেন্ডে রিপিট হয়।

ফলাফল

নিচের ভিডিওতে আইকন বোতাম ও কাউন্টার সহ UI দেখানো হয়েছে:

ছবি ৩. দুটি আইকন বোতাম (যোগ ও বিয়োগ) সহ একটি কাউন্টার UI যা কাউন্টারকে বাড়ায় ও কমায়।

অতিরিক্ত রিসোর্স