أزرار الرموز

تعرِض أزرار الرموز الإجراءات التي يمكن للمستخدمين اتّخاذها. يجب أن تستخدم أزرار الرموز رمزًا له معنى واضح، وعادةً ما تمثّل إجراءات شائعة أو يتم استخدامها بشكل متكرّر.

هناك نوعان من أزرار الرموز:

  • تلقائي: يمكن أن تفتح هذه الأزرار عناصر أخرى، مثل قائمة أو بحث.
  • التبديل: يمكن أن تمثّل هذه الأزرار إجراءات ثنائية يمكن تفعيلها أو إيقافها، مثل "مفضّل" أو "إشارة مرجعية".
5 أزرار رمزية برموز مختلفة (الإعدادات والمزيد وما إلى ذلك) وبعضها مملوء، ما يشير إلى أنّه تم اختياره، وبعضها مخطّط.
الشكل 1. أزرار الرموز، التي يكون بعضها ملونًا بالكامل (يشير إلى الاختيار) و مخطَّطًا.

واجهة برمجة التطبيقات

استخدِم العنصر القابل للتجميع IconButton لتنفيذ أزرار الرموز العادية. ل إنشاء أنماط مرئية مختلفة، مثل الأشكال الملونة أو الملونة المموّهة أو المخطّطة، استخدِم FilledIconButton وFilledTonalIconButton و OutlinedIconButton على التوالي.

تشمل المَعلمات الرئيسية لـ IconButton ما يلي:

  • onClick: دالة LAMBDA يتم تنفيذها عندما ينقر المستخدم على زر الرمز.
  • 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 يحتوي على قيمة boolean، وهي false في البداية. وهذا يجعل isToggled عنصرًا يحتفظ بالحالة، ما يعني أنّ Compose يعيد إنشاء واجهة المستخدم كلما تغيّرت قيمته.
    • يضمن rememberSaveable استمرار حالة isToggled على الرغم من تغييرات الضبط، مثل تدوير الشاشة.
  • تحدّد دالة onClick لعنصر IconButton سلوك الزر عند النقر عليه، ما يؤدي إلى تبديل الحالة بين true وfalse.
  • تحمِّل مَعلمة painter في العنصر القابل للتجميع Icon بشكل مشروط painterResource مختلفًا استنادًا إلى حالة isToggled. يؤدي ذلك إلى تغيير المظهر المرئي للرمز.
    • إذا كان isToggled هو true، يتم تحميل العنصر القابل للرسم للقلب الممتلئ.
    • إذا كانت القيمة isToggled هي false، يتم تحميل العنصر القابل للرسم الذي يمثّل قلبًا مخطّطًا.
  • يتم أيضًا تعديل contentDescription في Icon استنادًا إلى حالة isToggled لتوفير معلومات مناسبة حول تسهيل الاستخدام.

النتيجة

تعرض الصورة التالية زر رمز الإيقاف/التفعيل من المقتطف السابق في حالته غير المحدّدة:

زر رمز التبديل المفضّل (قلب) في حالته غير المحدّدة (غير مملوء)
الشكل 2. زر رمز الإيقاف/التفعيل "العناصر المفضّلة" في حالة عدم اختياره

مثال متقدّم: إجراءات متكرّرة عند الضغط

يوضّح هذا القسم كيفية إنشاء أزرار رموز تؤدي باستمرار إلى تنفيذ إجراء ما بينما يضغط المستخدم عليها ويُمسكها، بدلاً من تنفيذه مرة واحدة فقط لكل نقرة.

@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 أن يكون التأخير 1 ملي ثانية على الأقل لمنع تكرار الطلبات بشكل لانهائي.
    • يتمّ استدعاء pressedListener بعد كل تأخير داخل الحلقة. يؤدي ذلك إلى تكرار الإجراء.
  • يستخدم pressedListener rememberUpdatedState لضمان أنّ onClick lambda (الإجراء الذي سيتم تنفيذه) هو دائمًا أحدث 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 لإنشاء واجهة مستخدم ل زيادة مقياس وخفضه.
  • ويحافظ على متغيّر حالة قابل للتغيير pressedCount باستخدام remember و mutableIntStateOf، ويتم إعداده على القيمة 0. عند تغيير pressedCount، تتم إعادة تركيب أي عناصر تركيبية ترصده (مثل العنصر التركيبى Text) لتعكس القيمة الجديدة.
  • يؤدي النقر على MomentaryIconButton الأول أو الضغط عليه مع الاستمرار إلى خفض pressedCount.
  • يؤدي النقر على MomentaryIconButton الثاني أو الإبقاء عليه إلى زيادة pressedCount.
  • يستخدم كلا الزرَّين stepDelay تبلغ مدته 100 ملي ثانية، ما يعني أنّ الإجراء onClick يتكرر كل 100 ملي ثانية أثناء الضغط على أحد الزرَّين.

النتيجة

يعرض الفيديو التالي واجهة المستخدم التي تتضمّن أزرار الرموز والعداد:

الشكل 3. واجهة مستخدم للعداد تتضمّن زرَّي رمز (علامة الإضافة وعلامة الطرح) لزيادة العداد أو إنقاصه

مراجع إضافية