আইকন বোতাম

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

আইকন বোতাম দুই ধরনের হয়:

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

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 প্যারামিটার শর্তসাপেক্ষে isToggled স্টেট অনুযায়ী একটি আলাদা painterResource লোড করে। এটি আইকনের ভিজ্যুয়াল রূপ পরিবর্তন করে।
    • isToggled যদি true হয়, তাহলে এটি ভর্তি হার্ট ড্রয়েবল লোড করে।
    • isToggled যদি false হয়, তাহলে এটি আউটলাইন করা হার্ট ড্রয়েবল লোড করে।
  • Icon-এর contentDescription-ও isToggled স্টেটের উপর ভিত্তি করে আপডেট হয় যাতে অ্যাক্সেসিবিলিটি সংক্রান্ত উপযুক্ত তথ্য প্রদান করা যায়।

ফলাফল

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

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

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

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

@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 ট্রু হিসেবে বিবেচিত হয় এবং অন্যথায় ফলস হিসেবে বিবেচিত হয়। isPressed, true হলে, LaunchedEffect লুপে প্রবেশ করে।
    • এই লুপের মধ্যে, এটি ট্রিগার অ্যাকশনের মধ্যে পজ তৈরি করতে delay (stepDelay সহ) ব্যবহার করে। coerceIn নিশ্চিত করে যে ইনফিনিট লুপ প্রতিরোধ করতে দেরিটি কমপক্ষে ১ মিলি সেকেন্ডের হয়।
    • লুপের মধ্যে প্রতিটি বিলম্বের পরে 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 কম্পোজেবল একটি Row দেখায় যাতে দুটি MomentaryIconButton ইনস্ট্যান্স এবং একটি Text কম্পোজেবল থাকে যা কাউন্টার বাড়ানো এবং কমানোর জন্য একটি UI তৈরি করে।
  • এটি remember এবং mutableIntStateOf ব্যবহার করে একটি pressedCount পরিবর্তনশীল স্টেট ভেরিয়েবল বজায় রাখে, যা 0-তে ইনিশিয়ালাইজ করা হয়। pressedCount পরিবর্তন হলে, এটি পর্যবেক্ষণ করা যেকোনও কম্পোজেবল (যেমন Text কম্পোজেবল) নতুন ভ্যালু দেখানোর জন্য আবার কম্পোজ করে।
  • ক্লিক করলে বা ধরে রাখলে প্রথম MomentaryIconButton pressedCount কমে যায়।
  • ক্লিক করলে বা হোল্ড করলে দ্বিতীয় MomentaryIconButton pressedCount বৃদ্ধি পায়।
  • দুটি বোতামই ১০০ মিলিসেকেন্ডের stepDelay ব্যবহার করে, যার অর্থ হল বোতামটি ধরে রাখার সময় onClick অ্যাকশনটি প্রতি ১০০ মিলিসেকেন্ডে পুনরাবৃত্তি হয়।

ফলাফল

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

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

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