Styl akapitu

Z tego artykułu dowiesz się, jak możesz zmienić styl tekstu akapitu. Aby ustawić styl na poziomie akapitu, możesz skonfigurować parametry takie jak textAlign i lineHeight lub zdefiniować własny styl ParagraphStyle.

Ustawianie wyrównania tekstu

Parametr textAlign umożliwia ustawienie wyrównania w poziomie w obrębie obszaru kompozycyjnego Text.

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

  • Lewa krawędź kontenera Text dla alfabetu pisanego od lewej do prawej, np. alfabetu łacińskiego, cyrylicy lub hangula
  • Prawa krawędź kontenera Text dla alfabetu pisanego od prawej do lewej, np. arabskiego lub 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 elementu kompozycyjnego Text, użyj odpowiednio TextAlign.Start i TextAlign.End zamiast TextAlign.Left i TextAlign.Right, ponieważ są one ustawiane względem prawej krawędzi elementu kompozycyjnego Text w zależności od preferowanej orientacji języka. Na przykład TextAlign.End wyrównuje prawa do prawej w przypadku tekstu w języku francuskim i do lewej w przypadku tekstu arabskiego, a TextAlign.Right – do prawej niezależnie od użytego alfabetu.

Dodawanie wielu stylów do akapitu

Aby dodać wiele stylów w akapicie, możesz użyć symbolu ParagraphStyle w elemencie AnnotatedString, do którego można dodawać adnotacje z zastosowaniem stylów dowolnych adnotacji. Gdy część tekstu zostanie oznaczona za pomocą znaku ParagraphStyle, ta część zostanie oddzielona od pozostałego tekstu tak, jakby miała ona miejsce na początku i na końcu tekstu.

Więcej informacji o dodawaniu wielu stylów w tekście znajdziesz w sekcji Dodawanie wielu stylów w tekście.

AnnotatedString ma narzędzie do tworzenia bezpieczne dla typu, które 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 i zwykły czarny

Dostosowywanie wysokości linii i dopełnienia

includeFontPadding to starsza usługa, która dodaje dodatkowe dopełnienie na podstawie danych czcionek u góry pierwszego wiersza i u dołu ostatniego wiersza tekstu. Od funkcji BOM w wersji 2024.01.01 opcja 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 niczym nowa – jest dostępna od Androida Q. Możesz skonfigurować lineHeight dla Text za pomocą parametru lineHeight, który rozkłada wysokość wiersza w każdym wierszu tekstu. Za pomocą nowego elementu LineHeightStyle API możesz dokładniej skonfigurować sposób wyrównywania tekstu w pokoju i usunąć odstępy.

Aby zwiększyć precyzję, możesz dostosować wartość lineHeight za pomocą jednostki tekstowej „em” (względnego rozmiaru czcionki) zamiast „sp” (skalowanego pikseli). Więcej informacji o wybieraniu odpowiedniej jednostki tekstowej znajdziesz w artykule TextUnit.

Obraz przedstawiający parametr lineHeight jako pomiar na podstawie linii znajdujących się bezpośrednio nad i pod nim.
Rysunek 1. Użyj opcji Wyrównanie i Przytnij, aby dostosować tekst w zestawie lineHeight i przyciąć dodatkowy odstęp w razie potrzeby.

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

Poza dostosowaniem funkcji lineHeight możesz teraz dodatkowo wyśrodkować i określić styl tekstu za pomocą konfiguracji za pomocą eksperymentalnych interfejsów API LineHeightStyle: LineHeightStyle.Alignment i LineHeightStyle.Trim (includeFontPadding musi mieć wartość false, aby funkcja przycinania) działała. Wyrównanie i przycięcie wykorzystują odstępy między wierszami tekstu, aby lepiej rozłożyć je na wszystkie wiersze – w tym jeden wiersz tekstu i górny wiersz bloku tekstu.

LineHeightStyle.Alignment określa, jak wyrównać linię w przestrzeni określonej przez wysokość wiersza. W każdym wierszu możesz wyrównać tekst do góry, do dołu, do środka lub proporcjonalnie. LineHeightStyle.TrimNastępnie możesz opuścić lub usunąć dodatkową spację u góry pierwszego i u dołu ostatniego wiersza tekstu, wygenerowaną na podstawie wszelkich dostosowań lineHeight i wyrównania. Te przykłady pokazują, jak tekst wielowierszowy wygląda w różnych konfiguracjach LineHeightStyle.Trim po wyrównaniu (LineHeightStyle.Alignment.Center).

Obraz przedstawiający element LineHeightStyle.Trim.None Obraz pokazujący wysokość linii
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Obraz pokazujący wysokość Linii.Wyrównanie.PierwszaLiniaTop Obraz przedstawiający element LineHeightStyle.Trim.LastLinebottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Przeczytaj post na blogu Naprawianie dopełniania czcionek w tekście tworzenia, aby dowiedzieć się więcej o kontekście tej zmiany, sposobie działania usługi includeFontPadding w systemie widoków, a także o zmianach wprowadzonych w interfejsach API LineHeightStyle do tworzenia wiadomości.

Wstaw podziały wiersza

Interfejs API LineBreak określa kryteria, według których tekst jest podzielony na wiele wierszy. Typ podziału wiersza możesz określić w bloku TextStyle funkcji kompozycyjnej Text. Gotowe ustawienia podziału wierszy to między innymi:

  • Simple – szybkie, podstawowe podziały wierszy. Zalecany w przypadku pól do wprowadzania tekstu.
  • Heading – podział wiersza przy mniej restrykcyjnych zasadach. Zalecany w przypadku krótkich tekstów, np. tytułów,
  • Paragraph – wolniejsze, wyższej jakości podział wierszy zapewniający lepszą czytelność. Zalecane w przypadku dużej ilości tekstu, np. akapitów.

Ten fragment kodu używa zarówno właściwości Simple, jak i Paragraph, aby określić sposób podziału wiersza w przypadku długiego 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 przedstawiający prostą strategię podziału wiersza w porównaniu z blokiem tekstowym ze strategią podziału tekstu zoptymalizowaną pod kątem akapitów. Blok tekstowy ze strategią podziału wiersza
ma większą zmienność długości wiersza.
Rysunek 1. Blok tekstowy z prostą strategią podziału wierszy (u góry) w porównaniu z blokiem tekstowym zoptymalizowanym pod kątem akapitu (u dołu).

W powyższych danych wyjściowych widać, że podział wiersza Paragraph daje bardziej zrównoważony wizualnie wynik niż podział wiersza Simple.

Dostosuj podziały 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 wyważyć długość wierszy tekstu, a także stosuje automatyczne łączenie (jeśli jest włączone). Zalecane na małych ekranach, np. zegarków, aby zmaksymalizować ilość wyświetlanego tekstu.
  • HighQuality – optymalizuje akapit, aby zwiększyć czytelność tekstu, z uwzględnieniem łączników (jeśli jest włączone). (powinna to być wartość domyślna w przypadku wszystkich właściwości innych niż Balanced i Simple).
  • Simple – podstawowa, szybka strategia. Gdy ta opcja jest włączona, łączniki są stosowane tylko w przypadku słów, które same nie mieszczą się w całym wierszu. Ta opcja jest przydatna podczas edycji tekstu, aby nie zmieniać położenia 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 ze strategią 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ą podziału wierszy oraz akapitem sformatowanym bez strategii. Akapit ze zrównoważoną strategią podziału wierszy ma większą długość wierszy niż domyślna.
Rysunek 2. Akapit sformatowany przy użyciu strategii podziału wierszy Balanced (na górze) zamiast akapitu sformatowanego bez strategii podziału wierszy.

Uwagi 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. Może się zdarzyć, że efekty ich działania nie będą widoczne w językach innych niż CJK. Reguły podziału wierszy są ogólnie definiowane na podstawie języka.

Strictness opisuje rygorystyczność podziału wiersza za pomocą tych właściwości:

  • Default – domyślne reguły łamiące dla regionu. Może odpowiadać wartości Normal lub Strict.
  • Loose – najmniej restrykcyjne reguły. Odpowiednie dla krótkich linii.
  • Normal – najczęstsze reguły podziału wierszy.
  • Strict – najbardziej rygorystyczne reguły podziału wierszy.

WordBreak określa sposób wstawiania podziałów wierszy w słowach o tych właściwościach:

  • Default – domyślne reguły łamiące dla regionu.
  • Phrase – podział wiersza jest określany na podstawie wyrażeń.

Ten fragment kodu używa rygorystyczności Strict i ustawienia podziału słów w polu Phrase w przypadku tekstu w języku japońskim:

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 w języku japońskim z ustawieniami rygorystyczności i podziałem słów w porównaniu z tekstem domyślnym.
Rysunek 3. Tekst sformatowany za pomocą ustawień Strictness i WordBreak (u góry), a nie tylko za pomocą funkcji LineBreak.Heading (u dołu).

Łączy tekst w wierszach

Interfejs API Hyphens umożliwia dodanie obsługi myślnika do aplikacji. Łączenie polega na wstawieniu znaku interpunkcyjnego przypominającego myślnik, który wskazuje, że słowo jest podzielone na wiersze tekstu. Gdy ta opcja jest włączona, łącznik jest dodawany między sylabami słowa w odpowiednich miejscach.

Domyślnie łącznik nie jest włączony. 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
                )
            )
        }
    )
)

Akapit bez łącznika i akapit z włączonym łącznikiem.
  Gdy łącznik jest włączony, słowo jest łączone i dzielone na 2 wiersze.
Rysunek 4. Akapit bez łącznika (u góry) i akapit z włączonym łącznikiem (u dołu).

Gdy ta opcja jest włączona, łączenie odbywa się tylko w tych sytuacjach:

  • Słowo nie mieści się w wierszu. Jeśli stosujesz strategię podziału wiersza Simple, łącznik słowa występuje tylko wtedy, gdy linia tekstu jest krótsza niż pojedyncze słowo.
  • Odpowiednie ustawienie regionalne jest ustawiane na urządzeniu po określeniu odpowiedniego łącza za pomocą słowników dostępnych w systemie.