نمط الفقرة

تصف هذه الصفحة كيف يمكنك تصميم نص لفقرتك. لضبط نمط على مستوى الفقرة، يمكنك ضبط معلَمات مثل 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 هو سمة قديمة تضيف مساحة متروكة إضافية استنادًا إلى مقاييس الخط في أعلى السطر الأول وأسفل السطر الأخير من النص. بدءًا من الإصدار 2024.01.01 من Compose BOM، يتم ضبط includeFontPadding على false تلقائيًا، ما يجعل تنسيق النص التلقائي أكثر توافقًا مع أدوات التصميم الشائعة.

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

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

صورة تعرض lineHeight كقياس على الخطوط التي تظهر فوقها وتحتها مباشرةً.
الشكل 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: 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

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

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

تحدِّد واجهة برمجة التطبيقات LineBreak المعايير التي يتم من خلالها تقسيم النص على عدة أسطر. يمكنك تحديد نوع فاصل الأسطر الذي تريده في الجزء 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 (في الأعلى) مقابل فقرة منسّقة بدون استراتيجية لتقسيم الأسطر.

اعتبارات CJK

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

توضّح 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
    )
)

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

واصلة النص مقسّمة على أسطر

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

لا يتم تفعيل الواصلة تلقائيًا. لتفعيل الواصلة، أضِف 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، لا تحدث واصلة الكلمة إلا إذا كان السطر أقصر من الكلمة المفردة.
  • يتم تعيين اللغة المناسبة على جهازك، كما يتم تحديد الواصلة المناسبة باستخدام القواميس المتوفرة على النظام.