פסקת סגנון

בדף הזה נסביר איך לעצב טקסט בפסקה. כדי להגדיר סגנון ברמת הפסקה, אפשר להגדיר פרמטרים כמו 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 עבור 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 API הניסיוני: LineHeightStyle.Alignment ו-LineHeightStyle.Trim (צריך להגדיר את includeFontPadding לערך false כדי שהתכונה Trim תפעל). התכונות 'יישור' ו'חיתוך' משתמשות במרחב שנמדד בין שורות הטקסט כדי לחלק אותו בצורה הולמת יותר בין כל השורות, כולל שורה אחת של טקסט והשורה העליונה של מקטע טקסט.

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

בפוסט בבלוג תיקון של הרווח מסביב לגופן בטקסט שכותבים תוכלו לקרוא מידע נוסף על ההקשר של השינוי הזה, על האופן שבו includeFontPadding פועל במערכת התצוגה ועל השינויים שבוצעו ב-Compose ובממשקי ה-API החדשים של LineHeightStyle.

הוספת מעברי שורה

ממשק ה-API LineBreak מגדיר את הקריטריונים שבאמצעותם הטקסט מחולק לכמה שורות. אפשר לציין את סוג הפסקה שרוצים בשורה בבלוק TextStyle של ה-composable‏ 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 באמצעות ממשקי ה-API Strictness ו-WordBreak, שתוכננו במיוחד לשפות CJK. יכול להיות שלא תמיד תראו את ההשפעות של ממשקי ה-API האלה בשפות שאינן 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
    )
)

טקסט ביפנית עם הגדרות Strictness ו-WordBreak לעומת טקסט ברירת המחדל.
איור 3. טקסט שעבר עיצוב באמצעות ההגדרות של Strictness ו-WordBreak (למעלה) לעומת טקסט שעבר עיצוב רק באמצעות LineBreak.Heading (למטה).

הוספת מקפים לטקסט שמפוצל לשורות

באמצעות ממשק ה-API של 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 לחלוקת שורות, המילה תוחצה רק אם השורה קצרה יותר מהמילה היחידה.
  • השפה והאזור שמוגדרים במכשיר קובעים את ההפרדה המתאימה של מילים, על סמך מילונים שנמצאים במערכת.