إتاحة المحتوى القابل لتغيير الحجم من قِبل المستخدم

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

اختيار استراتيجية توسيع النطاق

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

مزيد من المعلومات: تؤكّد الأبحاث أنّ المحتوى الذي تتم إعادة تدفقه يكون أسهل في القراءة والتصفّح بالنسبة إلى المستخدمين الذين يعانون من ضعف في النظر، مقارنةً بالواجهات التي تتطلّب التحريك ثنائي الأبعاد. لمزيد من التفاصيل، يُرجى الاطّلاع على مقارنة بين المحتوى الذي يتكيّف مع حجم الشاشة والمحتوى الذي يتم عرضه باستخدام تقنية Pan-and-Scan على الأجهزة.

تغيير حجم جميع العناصر أو العناصر النصية فقط

يوضّح الجدول التالي التأثير المرئي لكل استراتيجية تغيير حجم.

الاستراتيجية تغيير حجم الكثافة تغيير حجم الخط

السلوك

يغيّر حجم كل العناصر بشكل متناسب. تتم إعادة تدفق المحتوى ليلائم الحاوية، لذلك لا يحتاج المستخدم إلى التحريك أفقيًا لرؤية كل المحتوى.

يؤثر ذلك في العناصر النصية فقط. ويظل التنسيق العام والمكوّنات غير النصية بالحجم نفسه.

What Scales

جميع العناصر المرئية: النص والمكوّنات (الأزرار والرموز) والصور وتباعُد التنسيق (الهوامش الداخلية والخارجية)

النص فقط

عرض توضيحي

الاقتراحات

بعد أن اطّلعت على الاختلافات المرئية، يساعدك الجدول التالي في الموازنة بين المزايا والعيوب واختيار أفضل استراتيجية للمحتوى الخاص بك.

نوع واجهة المستخدم

الاستراتيجية المقترَحة

الاستدلال

التنسيقات التي تركّز على القراءة

أمثلة: المقالات الإخبارية وتطبيقات المراسلة

الكثافة أو تغيير حجم الخط

يُفضَّل استخدام ميزة "تغيير حجم الكثافة" لتغيير حجم منطقة المحتوى بأكملها، بما في ذلك الصور المضمّنة.

يُعدّ تغيير حجم الخط بديلاً بسيطًا إذا كان المطلوب هو تغيير حجم النص فقط.

التصاميم المنظَّمة بصريًا

أمثلة: متاجر التطبيقات، وخلاصات وسائل التواصل الاجتماعي

تغيير حجم الكثافة

يحافظ على العلاقات المرئية بين الصور والنصوص في لوحات العرض الدوّارة أو الشبكات. تتجنّب طبيعة إعادة التدفق العرض الأفقي، ما قد يتعارض مع عناصر الانتقال المُدمجة.

رصد إيماءات تغيير الحجم في Jetpack Compose

لإتاحة المحتوى القابل للتكبير أو التصغير من قِبل المستخدم، عليك أولاً رصد الإيماءات عبر اللمس بأكثر من إصبع. في Jetpack Compose، يمكنك إجراء ذلك باستخدام Modifier.transformable.

المعدِّل transformable هو واجهة برمجة تطبيقات عالية المستوى توفّر الفرق zoomChange منذ آخر حدث إيماءة. يؤدي ذلك إلى تبسيط منطق تعديل الحالة إلى التراكم المباشر (على سبيل المثال، scale *= zoomChange)، ما يجعله مثاليًا لاستراتيجيات التوسيع التكيُّفي التي يتناولها هذا الدليل.

أمثلة على عمليات التنفيذ

توضّح الأمثلة التالية كيفية تنفيذ استراتيجيات تغيير حجم الكثافة وتغيير حجم الخط.

تغيير حجم الكثافة

يؤدي هذا النهج إلى تغيير حجم density الأساسي لمنطقة واجهة المستخدم. ونتيجةً لذلك، يتم تغيير حجم جميع القياسات المستندة إلى التنسيق، بما في ذلك المساحة المتروكة والتباعد وأحجام المكوّنات، كما لو كان حجم الشاشة أو درجة الدقة قد تغيّرا. بما أنّ حجم النص يعتمد أيضًا على الكثافة، يتم أيضًا تغيير حجمه بشكل متناسب. تكون هذه الاستراتيجية فعّالة عندما تريد تكبير جميع العناصر بشكل موحّد ضمن منطقة معيّنة، مع الحفاظ على التناسق المرئي العام ونِسب واجهة المستخدم.

private class DensityScalingState(
    // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x.
    private val minScale: Float = 0.75f,
    private val maxScale: Float = 3.5f,
    private val currentDensity: Density
) {
    val transformableState = TransformableState { zoomChange, _, _ ->
        scaleFactor.floatValue =
            (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale)
    }
    val scaleFactor = mutableFloatStateOf(1f)
    fun scaledDensity(): Density {
        return Density(
            currentDensity.density * scaleFactor.floatValue,
            currentDensity.fontScale
        )
    }
}

@Composable
fun DensityScalingSample() {
    val currentDensity = LocalDensity.current
    val scaleState =
        remember(currentDensity) { DensityScalingState(currentDensity = currentDensity) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .transformable(state = scaleState.transformableState),
        contentAlignment = Alignment.TopCenter
    ) {
        CompositionLocalProvider(
            LocalDensity provides scaleState.scaledDensity()
        ) {
            DemoCard()
        }
    }
}

تغيير حجم الخط

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

class FontScaleState(
    // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x.
    private val minScale: Float = 0.75f,
    private val maxScale: Float = 3.5f,
    private val currentDensity: Density
) {
    val transformableState = TransformableState { zoomChange, _, _ ->
        scaleFactor.floatValue =
            (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale)
    }
    val scaleFactor = mutableFloatStateOf(1f)
    fun scaledFont(): Density {
        return Density(
            currentDensity.density,
            currentDensity.fontScale * scaleFactor.floatValue
        )
    }
}

@Composable
fun FontScalingSample() {
    val currentDensity = LocalDensity.current
    val scaleState = remember { FontScaleState(currentDensity = currentDensity) }

    Box(
        modifier = Modifier
            .fillMaxSize()
            .transformable(state = scaleState.transformableState),
        contentAlignment = Alignment.TopCenter
    ) {
        CompositionLocalProvider(
            LocalDensity provides scaleState.scaledFont()
        ) {
            DemoCard()
        }
    }
}

واجهة مستخدم مشتركة للعرض التوضيحي

هذه هي الدالة المركّبة المشتركة DemoCard التي يستخدمها المثالان السابقان لإبراز سلوكيات تغيير الحجم المختلفة.

@Composable
private fun DemoCard() {
    Card(
        modifier = Modifier
            .width(360.dp)
            .padding(16.dp),
        shape = RoundedCornerShape(12.dp)
    ) {
        Column(
            modifier = Modifier.padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            Text("Demo Card", style = MaterialTheme.typography.headlineMedium)
            var isChecked by remember { mutableStateOf(true) }
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text("Demo Switch", Modifier.weight(1f), style = MaterialTheme.typography.bodyLarge)
                Switch(checked = isChecked, onCheckedChange = { isChecked = it })
            }
            Row(verticalAlignment = Alignment.CenterVertically) {
                Icon(Icons.Filled.Person, "Icon", Modifier.size(32.dp))
                Spacer(Modifier.width(8.dp))
                Text("Demo Icon", style = MaterialTheme.typography.bodyLarge)
            }
            Row(
                Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Box(
                    Modifier
                        .width(100.dp)
                        .weight(1f)
                        .height(80.dp)
                        .background(Color.Blue)
                )
                Box(
                    Modifier
                        .width(100.dp)
                        .weight(1f)
                        .height(80.dp)
                        .background(Color.Red)
                )
            }
            Text(
                "Demo Text: Lorem ipsum dolor sit amet, consectetur adipiscing elit," +
                    " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                style = MaterialTheme.typography.bodyMedium,
                textAlign = TextAlign.Justify
            )
        }
    }
}

نصائح واعتبارات

لإنشاء تجربة أكثر دقة وسهولة في الاستخدام، ضع في اعتبارك التوصيات التالية:

  • ننصحك بتوفير عناصر تحكّم في تغيير الحجم لا تعتمد على الإيماءات: قد يواجه بعض المستخدمين صعوبة في استخدام الإيماءات. ولمساعدة هؤلاء المستخدمين، ننصحك بتوفير طريقة بديلة لتعديل المقياس أو إعادة ضبطه بدون الاعتماد على الإيماءات.
  • التصميم لجميع المقاييس: اختبِر واجهة المستخدم مع كل من ميزة تغيير الحجم داخل التطبيق وإعدادات الخط أو العرض على مستوى النظام. تأكَّد من أنّ تنسيقات تطبيقك تتكيّف بشكل صحيح بدون تعطُّل المحتوى أو تداخله أو إخفائه. تعرَّف على مزيد من المعلومات حول كيفية إنشاء تنسيقات تكيُّفية.