Styl akapitu

Na tej stronie opisujemy, jak dostosować styl tekstu akapitu. Aby ustawić styl na poziomie akapitu, możesz skonfigurować takie parametry jak textAlign i lineHeight, lub zdefiniować własny styl ParagraphStyle.

Ustawianie wyrównania tekstu

Parametr textAlign umożliwia ustawienie wyrównania tekstu w poziomie w obszarze kompozycyjnym Text.

Domyślnie Text wybiera naturalne wyrównanie tekstu na podstawie jego wartości treści:

  • Lewa krawędź kontenera Text dla alfabetów pisanych od lewej do prawej, takich jak alfabet łaciński, cyrylica czy hangul
  • Prawa krawędź kontenera Text dla alfabetów pisanych od prawej do lewej, np. arabskiego czy hebrajskiego

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

Słowa

Jeśli chcesz ręcznie ustawić wyrównanie tekstu w funkcji kompozycyjnej Text, lepiej jest użyć właściwości TextAlign.Start i TextAlign.End zamiast odpowiednio TextAlign.Left i TextAlign.Right, ponieważ odpowiadają one prawej krawędzi funkcji Text kompozycyjnej w zależności od preferowanej orientacji tekstu. Na przykład TextAlign.End – w przypadku tekstu w języku francuskim i lewej strony w przypadku tekstu arabskiego, a TextAlign.Right – do prawej, niezależnie od użytego alfabetu.

Dodawanie wielu stylów w akapicie

Aby dodać wiele stylów w akapicie, możesz użyć znaku ParagraphStyle w AnnotatedString, który może być oznaczany za pomocą dowolnych adnotacji. Gdy oznaczysz fragment tekstu za pomocą znaku ParagraphStyle, zostanie on oddzielony od pozostałego tekstu tak, jakby na początku i na końcu znajdowały się pliki z wierszami.

Więcej informacji o dodawaniu wielu stylów do tekstu znajdziesz w artykule Dodawanie wielu stylów do tekstu.

AnnotatedString ma kreator bezpieczeństwa do obsługi typu, który ułatwia tworzenie: buildAnnotatedString. Ten fragment kodu używa parametru buildAnnotatedString do ustawienia 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")
            }
        }
    )
}

Trzy akapity w 3 różnych stylach: niebieski, czerwony i pogrubiony oraz zwykły czarny

dostosować wysokość wiersza i dopełnienie;

includeFontPadding to starsza wersja usługi, która dodaje dopełnienie na podstawie danych o czcionkach u góry i na dole ostatniego wiersza tekstu. Począwszy od wersji BOM w wersji 2024.01.01, includeFontPadding ma domyślnie wartość false, dzięki czemu domyślny układ tekstu jest bardziej zgodny z popularnymi narzędziami do projektowania.

Możliwość konfigurowania lineHeight nie jest nowa – była dostępna od Androida Q. Możesz skonfigurować lineHeight dla Text za pomocą parametru lineHeight, który rozdziela wysokość wiersza w poszczególnych wierszach. Następnie za pomocą nowej funkcji LineHeightStyle API możesz dokładniej skonfigurować wyrównanie tekstu w pokoju i usunąć odstępy.

Aby zwiększyć precyzję, użyj jednostki tekstowej „em” (względnego rozmiaru czcionki), a nie „sp” (skalowanych pikseli). lineHeight możesz dostosować. Więcej informacji o wybieraniu odpowiedniej jednostki tekstowej znajdziesz w sekcji TextUnit.

Obraz przedstawiający wysokość elementu lineHeight jako pomiar w oparciu o linie bezpośrednio nad i pod spodem.
Rysunek 1. Użyj opcji Wyrównanie i Przytnij, aby dostosować tekst w zestawie lineHeight i w razie potrzeby przyciąć dodatkową spację.

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
            )
        )
    )
)

Oprócz dostosowywania elementu lineHeight możesz teraz dodatkowo wyśrodkować tekst i określić jego styl za pomocą konfiguracji za pomocą eksperymentalnego interfejsu API LineHeightStyle: LineHeightStyle.Alignment i LineHeightStyle.Trim (includeFontPadding, aby funkcja przycinania działała, musi mieć wartość includeFontPadding).false Wyrównanie i przycinanie wykorzystują wyrównany odstęp między wierszami tekstu, aby bardziej równomiernie rozłożyć go na wszystkie wiersze – w tym na 1 wiersz i górny wiersz bloku tekstu.

Parametr LineHeightStyle.Alignment określa, jak wyrównać linię w miejscu podanym przez wysokość wiersza. W każdym wierszu możesz go wyrównać do góry, na dole, do środka lub proporcjonalnie. LineHeightStyle.Trim pozwala następnie opuścić lub usunąć dodatkową spację u góry pierwszego wiersza i na dole ostatniego wiersza tekstu, wygenerowaną na podstawie wszystkich dostosowań lineHeight i wyrównania. Poniższe przykłady pokazują, jak tekst wielowierszowy wygląda w różnych konfiguracjach LineHeightStyle.Trim po wyśrodkowaniu (LineHeightStyle.Alignment.Center).

Obraz pokazujący element LineHeightStyle.Przytnij.None Obraz pokazujący element LineHeightStyle.Przytnij.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Obraz przedstawiający element LineHeightStyle.Przytnij.FirstLineTop Obraz przedstawiający element LineHeightStyle.Przytnij.LastLinebottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Przeczytaj posta na blogu Naprawianie dopełnienia czcionek w funkcji tworzenia tekstu, aby dowiedzieć się więcej o kontekście tej zmiany, sposobie działania usługi includeFontPadding w systemie widoku danych, a także zmianach wprowadzonych w funkcji tworzenia wiadomości i nowych interfejsach API LineHeightStyle.

Wstaw podziały wierszy

Interfejs API LineBreak definiuje kryteria, według których tekst jest dzielony na wiele wierszy. Typ podziału wiersza możesz określić w bloku TextStyle funkcji kompozycyjnej Text. Gotowe typy podziału wiersza to m.in.:

  • Simple – szybkie, proste łamanie linii. Zalecane w przypadku pól do wprowadzania tekstu.
  • Heading – łamanie wiersza z luźniejszymi regułami łamania. Zalecany w przypadku krótkich tekstów, np. tytułów.
  • Paragraph – wolniejsze łamanie wierszy o wyższej jakości dla lepszej czytelności. Zalecane w przypadku dużej ilości tekstu, np. akapitów.

Ten fragment kodu używa Simple i Paragraph do określenia sposobu podziału wierszy w długim bloku tekstu:

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
                )
            )
        }
    )
)

Blok tekstowy, który pokazuje prostą strategię przerywania wierszy oraz blok tekstowy ze strategią łamania zoptymalizowaną pod kątem akapitu. Blok tekstowy z prostą strategią podziału wiersza ma większą zmienność długości wierszy.
Rysunek 1. Blok tekstowy z prostą strategią podziału wiersza (u góry) i blokiem tekstowym z podziałem wiersza zoptymalizowanym pod kątem akapitu (u dołu).

W powyższych danych wyjściowych warto zauważyć, że w przypadku podziału wiersza Paragraph wynik jest bardziej zrównoważony wizualnie niż dzielenie wiersza Simple.

Dostosowywanie podziałów wierszy

Możesz też utworzyć własną konfigurację LineBreak za pomocą parametru Strategy. Strategy może być dowolnym z tych elementów:

  • Balanced – próbuje zrównoważyć długości wierszy tekstu z zastosowaniem automatycznego łącznika, jeśli jest włączone. Zalecane na małe ekrany, takie jak zegarki, aby wyświetlać jak najwięcej tekstu.
  • HighQuality – optymalizuje akapit, by zwiększyć czytelność tekstu (także łącznik, jeśli jest włączony). (Powinien to być wartość domyślna w przypadku wszystkich innych wartości niż Balanced i Simple).
  • Simple – podstawowa, szybka strategia. Gdy ta opcja jest włączona, łącznik jest używany tylko dla słów, które same nie mieszczą się w całym wierszu. Przydaje się podczas edytowania tekstu, by nie zmieniać pozycji podczas pisania.

Ten fragment kodu pokazuje różnicę między akapitem z ustawieniami domyślnymi a akapitem zoptymalizowanym pod kątem małych ekranów przy użyciu strategii podziału wierszy 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
            )
        }
    )
)

Akapit ze zrównoważoną strategią przerywania wierszy oraz akapit sformatowany bez strategii. Akapit ze strategią łamania wierszy ma bardziej stabilną długość wierszy niż domyślna.
Rysunek 2. Akapit sformatowany zgodnie ze strategią podziału wiersza Balanced (u góry) i akapitu sformatowanym bez strategii podziału wiersza.

Uwagi dotyczące CJK

Możesz też dostosować LineBreak za pomocą interfejsów API Strictness i WordBreak, które zostały zaprojektowane specjalnie pod kątem języków CJK. Efekty działania tych interfejsów API nie zawsze są widoczne w językach innych niż CJK. Ogólnie reguły podziału wierszy są definiowane na podstawie języka.

Strictness określa stopień dokładności podziału wiersza za pomocą tych właściwości:

  • Default – domyślne reguły naruszające zasady dla danego języka. Może odpowiadać wartości Normal lub Strict.
  • Loose – najmniej restrykcyjne reguły. Odpowiedni dla krótkich linii.
  • Normal – najpopularniejsze reguły łamania wierszy.
  • Strict – najbardziej rygorystyczne reguły łamania wierszy.

Parametr WordBreak określa, jak powinny być wstawiane podziały wierszy w słowach o tych właściwościach:

  • Default – domyślne reguły naruszające zasady dla danego języka.
  • Phrase – podział wierszy opiera się na wyrażeniach.

Ten fragment kodu używa rygorystyczności Strict i ustawień podziału słów w tekście w języku japońskim 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
    )
)

Tekst japoński z ustawieniami Ścisłości i Podziału słów w porównaniu z tekstem domyślnym.
Rysunek 3. Tekst sformatowany z ustawieniami Strictness i WordBreak (u góry) a tekst sformatowany tylko przy użyciu LineBreak.Heading (u dołu).

Dziel tekst między wierszami

Interfejs API Hyphens umożliwia dodanie obsługi łączników do aplikacji. Łączenie oznacza wstawianie znaku interpunkcyjnego przypominającego myślnik, który zasygnalizuje, że słowo jest dzielone między wiersze tekstu. Gdy ta opcja jest włączona, łącznik pojawia się między sylabami słowa w odpowiednich miejscach.

Dzielenie łączników jest domyślnie wyłączone. Aby włączyć łącznik, dodaj Hyphens.Auto jako parametr w bloku 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
                )
            )
        }
    )
)

akapitu bez łączników, a także akapitu z włączonym dzieleniem.
  Gdy łącznik jest włączony, wyraz zostaje dzielony na 2 wiersze.
Rysunek 4. akapitu bez łącznika (u góry) i akapitów z włączonym dzieleniem (u dołu).

Gdy ta opcja jest włączona, łącznik pojawia się tylko wtedy, gdy:

  • Słowo nie mieści się w wierszu. Jeśli użyjesz strategii podziału wiersza Simple, łącznik słów nastąpi tylko wtedy, gdy wiersz jest krótszy od pojedynczego słowa.
  • Na urządzeniu jest ustawiony odpowiedni język, na podstawie którego łącznik jest określany na podstawie słowników dostępnych w systemie.