نمط الفقرة

توضّح هذه الصفحة كيفية تنسيق النص في فقرتك. لضبط التنسيق على مستوى الفقرة، يمكنك ضبط مَعلمات مثل textAlign وlineHeight أو تحديد ParagraphStyle خاص بك.

ضبط محاذاة النص

تتيح لك المَعلمة textAlign ضبط المحاذاة الأفقية للنص ضمن مساحة سطح Text القابلة للإنشاء.

تلقائيًا، ستختار Text المحاذاة الطبيعية للنص استنادًا إلى قيمة المحتوى:

  • الحافة اليسرى لحاوية Text للأبجديات التي تُكتب من اليسار إلى اليمين، مثل اللاتينية أو السيريلية أو الهانغول
  • الحافة اليمنى لحاوية Text للأبجديات التي تُكتب من اليمين إلى اليسار، مثل العربية أو العبرية

@Composable
fun CenterText() {
    Text(
        "Hello World", textAlign = TextAlign.Center, modifier = Modifier.width(150.dp)
    )
}

الكلمات

إذا أردت ضبط محاذاة النص يدويًا في عنصر Text قابل للإنشاء، يُفضَّل استخدام TextAlign.Start وTextAlign.End بدلاً من TextAlign.Left و TextAlign.Right على التوالي، لأنّهما يؤديان إلى الحافة اليمنى لعنصر Text القابل للإنشاء استنادًا إلى اتجاه النص في اللغة المفضّلة. على سبيل المثال، تتم المحاذاة إلى الجانب الأيمن باستخدام TextAlign.End للنص باللغة الفرنسية وإلى الجانب الأيسر للنص باللغة العربية، ولكن تتم المحاذاة إلى الجانب الأيمن باستخدام TextAlign.Right بغض النظر عن الأبجدية المستخدَمة.

إضافة أنماط متعددة في فقرة

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

لمزيد من المعلومات عن إضافة أنماط متعددة في نص، يُرجى الاطّلاع على مقالة إضافة أنماط متعددة في النص.

يحتوي AnnotatedString على أداة إنشاء آمنة من حيث النوع لتسهيل إنشائه: buildAnnotatedString. يستخدم المقتطف التالي buildAnnotatedString لضبط ParagraphStyle:

@Composable
fun ParagraphStyle() {
    Text(
        buildAnnotatedString {
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
                withStyle(style = SpanStyle(color = Color.Blue)) {
                    append("Hello\n")
                }
                withStyle(
                    style = SpanStyle(
                        fontWeight = FontWeight.Bold, color = Color.Red
                    )
                ) {
                    append("World\n")
                }
                append("Compose")
            }
        }
    )
}

ثلاث فقرات بثلاثة أنماط مختلفة: أزرق وأحمر وخط عريض وأسود عادي

ضبط ارتفاع السطر والمساحة المتروكة

includeFontPadding هي خاصية قديمة تضيف مساحة متروكة إضافية استنادًا إلى مقاييس الخط في أعلى السطر الأول وأسفل السطر الأخير من النص. اعتبارًا من إصدار Compose BOM 2024.01.01، يتم ضبط includeFontPadding على false تلقائيًا، ما يجعل تنسيق النص التلقائي أكثر اتساقًا مع أدوات التصميم الشائعة.

ليست إمكانية ضبط lineHeight جديدة، فقد كانت متاحة منذ Android Q. يمكنك ضبط lineHeight لـ Text باستخدام المَعلمة lineHeight، التي توزع ارتفاع السطر في كل سطر من النص. يمكنك بعد ذلك استخدام LineHeightStyle API لضبط كيفية محاذاة هذا النص ضمن المساحة وإزالة المسافة البيضاء.

قد تحتاج إلى ضبط lineHeight باستخدام وحدة النص "em" (حجم الخط النسبي ) بدلاً من "sp" (وحدات البكسل التي تم تغيير حجمها) لتحسين الدقة. لمزيد من المعلومات عن اختيار وحدة نص مناسبة، يُرجى الاطّلاع على TextUnit.

صورة تعرض ارتفاع السطر كوحدة قياس استنادًا إلى الأسطر التي تعلوه وتليه مباشرةً
الشكل 1. استخدِم "المحاذاة" و"الاقتطاع" لضبط النص ضمن lineHeight المضبوط، واقتطِع المساحة الإضافية إذا لزم الأمر.

Text(
    text = text,
    style = LocalTextStyle.current.merge(
        TextStyle(
            lineHeight = 2.5.em,
            platformStyle = PlatformTextStyle(
                includeFontPadding = false
            ),
            lineHeightStyle = LineHeightStyle(
                alignment = LineHeightStyle.Alignment.Center,
                trim = LineHeightStyle.Trim.None
            )
        )
    )
)

بالإضافة إلى ضبط lineHeight، يمكنك الآن توسيط النص وتنسيقه بشكل أكبر باستخدام عمليات الضبط من خلال LineHeightStyle API: LineHeightStyle.Alignment وLineHeightStyle.Trim (يجب ضبط includeFontPadding على false لكي يعمل الاقتطاع). تستخدم "المحاذاة" و"الاقتطاع" المساحة المقاسة بين أسطر النص لتوزيعها بشكل أكثر ملاءمة على جميع الأسطر، بما في ذلك سطر واحد من النص والسطر العلوي من فقرة نصية.

LineHeightStyle.Alignment تحدّد كيفية محاذاة السطر في المساحة التي يوفّرها ارتفاع السطر. ضمن كل سطر، يمكنك محاذاة النص إلى الأعلى أو الأسفل أو الوسط أو بشكل نسبي. بعد ذلك، يتيح لك LineHeightStyle.Trim ترك المساحة الإضافية أو إزالتها في أعلى السطر الأول وأسفل السطر الأخير من النص، والتي تم إنشاؤها من أي عمليات ضبط لـ lineHeight و"المحاذاة". توضّح النماذج التالية كيف يبدو النص المتعدد الأسطر مع إعدادات LineHeightStyle.Trim مختلفة عندما تكون المحاذاة في الوسط (LineHeightStyle.Alignment.Center).

صورة توضّح LineHeightStyle.Trim.None صورة توضّح LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
صورة توضّح LineHeightStyle.Trim.FirstLineTop صورة توضيحية تعرض LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

يُرجى الاطّلاع على منشور المدونة Fixing Font Padding in Compose Text لمزيد من المعلومات عن سياق هذا التغيير وكيفية عمل includeFontPadding في نظام العرض والتغييرات التي تم إجراؤها على Compose وواجهات LineHeightStyle APIs الجديدة.

إدراج فواصل أسطر

تحدّد LineBreak API المعايير التي يتم بموجبها تقسيم النص على أسطر متعددة. يمكنك تحديد نوع فاصل الأسطر الذي تريده في الـ TextStyle كتلة من الـ Text القابل للإنشاء. تشمل أنواع فواصل الأسطر المضبوطة مسبقًا ما يلي:

  • Simple : فاصل أسطر أساسي وسريع. يُنصح به لحقول إدخال النص.
  • Heading : فاصل أسطر مع قواعد فاصل أسطر أقل تقييدًا. يُنصح به للنصوص القصيرة، مثل العناوين.
  • Paragraph : فاصل أسطر أبطأ وأعلى جودة لتحسين قابلية القراءة. يُنصح به لكميات أكبر من النص، مثل الفقرات.

يستخدم المقتطف التالي كلاً من Simple وParagraph لتحديد سلوك فاصل الأسطر في فقرة طويلة من النص:

TextSample(
    samples = mapOf(
        "Simple" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Simple
                )
            )
        },
        "Paragraph" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph
                )
            )
        }
    )
)

كتلة نصية تعرض استراتيجية بسيطة لتقسيم الأسطر مقارنةً بكتلة نصية تستخدم استراتيجية تقسيم محسّنة للفقرات يحتوي كتلة النص التي تستخدم استراتيجية بسيطة لتقسيم الأسطر على تباين أكبر في أطوال الأسطر.
الشكل 1. فقرة نصية تستخدم استراتيجية فاصل أسطر بسيطة (أعلى) مقابل فقرة نصية تستخدم فاصل أسطر محسّنًا للفقرات (أسفل).

في الناتج أعلاه، لاحظ أنّ سلوك فاصل الأسطر Paragraph ينتج نتيجة أكثر توازنًا من الناحية المرئية من فاصل الأسطر Simple.

تخصيص فواصل الأسطر

يمكنك أيضًا إنشاء إعداد LineBreak خاص بك باستخدام المَعلمة Strategy. يمكن أن تكون Strategy أيًا مما يلي:

  • Balanced : يحاول موازنة أطوال أسطر النص، ويطبّق أيضًا الواصلة التلقائية إذا كانت مفعّلة. يُنصح به للشاشات الصغيرة، مثل الساعات، لزيادة كمية النص المعروض إلى أقصى حد.
  • HighQuality : يحسِّن فقرة لجعل النص أكثر قابلية للقراءة، بما في ذلك الواصلة إذا كانت مفعّلة. (يجب أن يكون هذا الإعداد تلقائيًا لكل ما ليس Balanced أو Simple.)
  • Simple : استراتيجية أساسية وسريعة. إذا كانت الواصلة مفعّلة، يتم تطبيقها فقط على الكلمات التي لا يمكن أن تظهر بمفردها في سطر كامل. مفيد لتعديل النص لتجنُّب تغيير المواضع أثناء الكتابة.

يوضّح المقتطف التالي الفرق بين فقرة تحتوي على الإعدادات التلقائية وفقرة محسّنة للشاشات الصغيرة باستخدام استراتيجية فاصل الأسطر Balanced:

TextSample(
    samples = mapOf(
        "Balanced" to {
            val smallScreenAdaptedParagraph =
                LineBreak.Paragraph.copy(strategy = LineBreak.Strategy.Balanced)
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(200.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = smallScreenAdaptedParagraph
                )
            )
        },
        "Default" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(200.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default
            )
        }
    )
)

فقرة تستخدم استراتيجية متوازنة لتقسيم الأسطر وفقرة منسّقة بدون استراتيجية تحتوي الفقرة التي تستخدم استراتيجية تقسيم الأسطر المتوازنة على أطوال أسطر أكثر اتساقًا من الفقرة التلقائية.
الشكل 2. فقرة منسَّقة باستخدام استراتيجية فاصل الأسطر Balanced (أعلى) مقابل فقرة منسَّقة بدون استراتيجية فاصل أسطر.

اعتبارات اللغات الصينية واليابانية والكورية

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

تصف Strictness مدى صرامة فاصل الأسطر باستخدام الخصائص التالية:

  • Default : قواعد فاصل الأسطر التلقائية للغة. قد تتطابق مع Normal أو Strict.
  • Loose : القواعد الأقل تقييدًا. مناسبة للأسطر القصيرة.
  • Normal : القواعد الأكثر شيوعًا لفاصل الأسطر.
  • Strict : القواعد الأكثر صرامة لفاصل الأسطر.

تحدّد WordBreak كيفية إدراج فواصل الأسطر ضمن الكلمات باستخدام الخصائص التالية:

  • Default : قواعد فاصل الأسطر التلقائية للغة.
  • Phrase : يستند فاصل الأسطر إلى العبارات.

يستخدم المقتطف التالي إعداد صرامة Strict وإعداد فاصل أسطر Phrase لنص باللغة اليابانية:

val customTitleLineBreak = LineBreak(
    strategy = LineBreak.Strategy.HighQuality,
    strictness = LineBreak.Strictness.Strict,
    wordBreak = LineBreak.WordBreak.Phrase
)
Text(
    text = "あなたに寄り添う最先端のテクノロジー。",
    modifier = Modifier.width(250.dp),
    fontSize = 14.sp,
    style = TextStyle.Default.copy(
        lineBreak = customTitleLineBreak
    )
)

نص ياباني مع إعدادات "الدقة" و"فاصل الكلمات" مقارنةً بالنص التلقائي
الشكل 3. نص منسَّق باستخدام إعدادات Strictness وWordBreak (أعلى) مقابل نص منسَّق باستخدام LineBreak.Heading فقط (أسفل).

وضع واصلة في النص المقسَّم على أسطر

تتيح لك Hyphens API إضافة دعم الواصلة إلى تطبيقك. الواصلة تشير إلى إدراج علامة ترقيم تشبه الشرطة للإشارة إلى أنّ كلمة مقسَّمة على أسطر من النص. عند تفعيل الواصلة، تتم إضافتها بين مقاطع الكلمة في نقاط الواصلة المناسبة.

تلقائيًا، لا تكون الواصلة مفعّلة. لتفعيل الواصلة، أضِف Hyphens.Auto كمَعلمة في كتلة TextStyle:

TextSample(
    samples = mapOf(
        "Hyphens - None" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph,
                    hyphens = Hyphens.None
                )
            )
        },
        "Hyphens - Auto" to {
            Text(
                text = SAMPLE_LONG_TEXT,
                modifier = Modifier
                    .width(130.dp)
                    .border(BorderStroke(1.dp, Color.Gray)),
                fontSize = 14.sp,
                style = TextStyle.Default.copy(
                    lineBreak = LineBreak.Paragraph,
                    hyphens = Hyphens.Auto
                )
            )
        }
    )
)

فقرة بدون تفعيل التوصيل وواحدة مع تفعيل التوصيل
  عند تفعيل التوصيل، يتم توصيل الكلمة وتقسيمها على سطرين.
الشكل 4. فقرة بدون تفعيل الواصلة (أعلى) مقابل فقرة تم تفعيل الواصلة فيها (أسفل).

عند تفعيل الواصلة، لا يتم تطبيقها إلا في الحالات التالية:

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