دکمه‌های نماد

دکمه‌های نمادین کنش‌هایی را که کاربران می‌توانند انجام دهند نمایش می‌دهند. دکمه‌های نمادین باید از نمادی با معنای واضح استفاده کنند و معمولاً نشان‌دهنده کنش‌های رایج یا پرکاربرد باشند.

دو نوع دکمه نماد وجود دارد:

  • پیش‌فرض: این دکمه‌ها می‌توانند عناصر دیگری مانند منو یا جستجو را باز کنند.
  • روشن/خاموش کردن: این دکمه‌ها می‌توانند نشان‌دهنده کنش‌های دوتایی باشند که می‌توانند روشن یا خاموش شوند، مانند «موردعلاقه» یا «نشانک».
‫۵ دکمه نماد با نمادهای مختلف (تنظیمات، بیشتر، و غیره). برخی‌از آن‌ها پر هستند که نشان‌دهنده انتخاب است و برخی دیگر خطوط پیرامونی دارند.
شکل ۱. دکمه‌های نمادین که برخی‌از آن‌ها پر هستند (نشان‌دهنده انتخاب) و برخی دیگر خطی هستند.

سطح میانای برنامه‌سازی کاربردی

از عنصر ترکیبی 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 میانای کاربر را بازترکیب می‌کند.
    • ‫rememberSaveable تضمین می‌کند که وضعیت isToggled در تغییرات پیکربندی، مانند چرخش صفحه‌نمایش، حفظ شود.
  • لامبدای onClick در IconButton رفتار دکمه را هنگام کلیک شدن تعریف می‌کند و وضعیت را بین true و false تغییر می‌دهد.
  • پارامتر painter در عنصر ترکیبی Icon به‌طور شرطی painterResource متفاوتی را براساس وضعیت isToggled بار می‌کند. این کار ظاهر دیداری نماد را تغییر می‌دهد.
    • اگر isToggled برابر با true باشد، طراحی کشیدنی قلب توپر را بار می‌کند.
    • اگر isToggled false باشد، قلب طراحی‌خطی بار می‌شود.
  • contentDescription Icon نیز براساس وضعیت 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 ترکیبی را برای ساختن میانای کاربری برای افزایش و کاهش شمارنده نمایش می‌دهد.
  • بااستفاده از remember و mutableIntStateOf، متغیر وضعیت تغییرپذیر pressedCount را که با ۰ مقداردهی اولیه شده است حفظ می‌کند. وقتی pressedCount تغییر می‌کند، هر ترکیب‌پذیری که آن را مشاهده می‌کند (مثل ترکیب‌پذیری Text) برای نشان دادن مقدار جدید دوباره ترکیب می‌شود.
  • اولین MomentaryIconButton با کلیک کردن یا نگه داشتن pressedCount کاهش می‌یابد.
  • با کلیک کردن یا نگه داشتن MomentaryIconButton دوم، pressedCount افزایش می‌یابد.
  • هر دو دکمه از stepDelay ۱۰۰ میلی‌ثانیه استفاده می‌کنند، یعنی onClick کنش هر ۱۰۰ میلی‌ثانیه یک‌بار هنگام نگه داشتن دکمه تکرار می‌شود.

نتیجه

ویدیو زیر میانای کاربری را با دکمه‌های نماد و شمارنده نشان می‌دهد:

شکل ۳. واسط کاربر شمارشگر با دو دکمه نماد (مثبت و منفی) که شمارشگر را افزایش و کاهش می‌دهند.

منابع بیشتر