Styl akapitu

Z tej strony dowiesz się, jak nadać styl tekstowi w akapicie. Aby ustawić stylizację na poziomie akapitu, możesz skonfigurować parametry takie jak textAlign i lineHeight lub zdefiniować własny parametr ParagraphStyle.

Ustawianie wyrównania tekstu

Parametr textAlign umożliwia ustawienie poziomego wyrównania tekstu w powierzchni Text.

Domyślnie Text wybiera naturalne wyrównanie tekstu w zależności od jego wartości treści:

  • Lewa krawędź kontenera Text w przypadku alfabetów pisanych od lewej do prawej, takich jak alfabet łaciński, cyrylica czy hangul
  • Prawa krawędź kontenera Text w przypadku alfabetów zapisywanych od prawej do lewej, takich jak arabski czy hebrajski

@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 komponowalnym Text, użyj funkcji TextAlign.StartTextAlign.End zamiast funkcji TextAlign.LeftTextAlign.Right, ponieważ te pierwsze dają lepszy efekt w przypadku prawej krawędzi kompozytowanego Text, w zależności od preferowanej orientacji tekstu w danym języku. Na przykład TextAlign.End jest wyrównywane po prawej stronie w przypadku tekstu francuskiego i po lewej w przypadku tekstu arabskiego, ale TextAlign.Right jest wyrównywane po prawej stronie niezależnie od użytego alfabetu.

.

Dodawanie wielu stylów w akapicie

Aby dodać wiele stylów w akapicie, możesz użyć ParagraphStyleAnnotatedString, który może być opatrzony adnotacjami w dowolnym stylu. Gdy część tekstu zostanie oznaczona symbolem ParagraphStyle, zostanie ona oddzielona od pozostałego tekstu tak, jakby miała spacje na początku i na końcu.

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

AnnotatedString ma konstruktor z funkcją ochrony typu, który ułatwia tworzenie: buildAnnotatedString. W tym fragmencie kodu parametr buildAnnotatedString służy do ustawiania parametru 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")
            }
        }
    )
}

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

Dostosowywanie wysokości wiersza i wypełniania

includeFontPadding to starsza właściwość, która dodaje dodatkowe wypełnienie na podstawie danych dotyczących czcionki u góry pierwszego wiersza i u dołu ostatniego wiersza tekstu. Począwszy od wersji 2024.01.01 pakietu Compose BOM, parametr includeFontPadding jest domyślnie ustawiony na false, co sprawia, że domyślny układ tekstu jest bardziej zgodny z popularnymi narzędziami do projektowania.

Możliwość konfigurowania lineHeight nie jest nowa – jest dostępna od Androida Q. Możesz skonfigurować lineHeight dla Text za pomocą parametru lineHeight, który rozprowadza wysokość linii na każdą linię tekstu. Następnie możesz użyć nowego elementu LineHeightStyle API, aby dostosować sposób wyrównania tekstu w pokoju i usunąć spacje.

Aby zwiększyć dokładność, możesz dostosować wartość lineHeight za pomocą jednostki tekstowej „em” (względny rozmiar czcionki) zamiast „sp” (skalowane piksele). Więcej informacji o wybieraniu odpowiedniej jednostki tekstowej znajdziesz w artykule TextUnit.

Obraz pokazujący wysokość linii jako pomiar na podstawie linii bezpośrednio nad nią i pod nią.
Rysunek 1. Aby dostosować tekst w ramach zestawu lineHeight, użyj opcji Wyrównaj i przytnij, a w razie potrzeby usuń nadmiar wolnej przestrzeni.

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 lineHeight możesz teraz dodatkowo wyśrodkować tekst i nadać mu styl za pomocą konfiguracji w interfejsie LineHeightStyle API: LineHeightStyle.Alignment i LineHeightStyle.Trim (aby funkcja Trim działała, includeFontPadding musi być ustawiony na false). Wyrównanie i przycięcie korzystają z mierzonego odstępu między wierszami tekstu, aby lepiej rozłożyć tekst na wszystkie wiersze, w tym na pojedynczy wiersz tekstu i wiersz na górze bloku tekstu.

LineHeightStyle.Alignment określa, jak wyrównać wiersz w przestrzeni zapewnionej przez wysokość wiersza. W każdej linii możesz wyrównać tekst do góry, do dołu, do środka lub proporcjonalnie. Opcja LineHeightStyle.Trim pozwala pozostawić lub usunąć dodatkową spację na początku pierwszego wiersza i na końcu ostatniego wiersza tekstu wygenerowanego na podstawie wszelkich korekt lineHeight i wyrównania. Poniższe przykłady pokazują, jak wygląda tekst wielowierszowy w różnych konfiguracjach LineHeightStyle.Trim, gdy wyrównanie jest ustawione na środku (LineHeightStyle.Alignment.Center).

Obraz pokazujący styl LineHeightStyle.Trim.None Ilustracja pokazująca styl LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Ilustracja pokazująca styl LineHeightStyle.Trim.FirstLineTop Ilustracja pokazująca styl LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Aby dowiedzieć się więcej o kontekście tej zmiany, sposobie działania funkcji includeFontPadding w systemie View oraz zmianach wprowadzonych w komponencie Compose i nowych interfejsach API LineHeightStyle, przeczytaj post na blogu na temat poprawiania odstępów w komponencie Compose.

Wstawianie podziałów wiersza

Interfejs API LineBreak definiuje kryteria, według których tekst jest dzielony na kilka wierszy. W bloku TextStyle w komponowalnym elemencie Text możesz określić, jaki typ dzielenia wiersza chcesz zastosować. Dostępne wstępnie typy dzielenia wiersza:

  • Simple – szybkie, podstawowe przerywanie linii. Zalecane w przypadku pól tekstowych.
  • Heading – przełamanie wiersza z mniej rygorystycznymi zasadami przełamania. Zalecane w przypadku krótkich tekstów, np. tytułów.
  • Paragraph – wolniejsze, wyższej jakości dzielenie wierszy w celu poprawy czytelności. Zalecane w przypadku większych ilości tekstu, np. akapitów.

Ten fragment kodu używa zarówno tagu Simple, jak i tagu Paragraph, aby określić sposób dzielenia 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 tekstu, który pokazuje prostą strategię dzielenia tekstu na linie w porównaniu z blokiem tekstu z optymalizacją podziału na akapity. Blok tekstu z prostą strategią dzielenia wierszy ma większą zmienność długości wierszy.
Rysunek 1. Blok tekstu z prostą strategią dzielenia wierszy (góra) w porównaniu z blokiem tekstu z optymalizacją dzielenia wierszy na poziomie akapitu (dół).

W powyższym wyjściu widać, że zachowanie Paragraph w przypadku dzielenia wiersza zapewnia bardziej zrównoważony wizualnie wynik niż zachowanie 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óba wyrównania długości wierszy tekstu, a także zastosowanie automatycznego dzielenia wyrazów, jeśli jest włączone. Zalecane na małych ekranach, np. na zegarkach, aby zmaksymalizować ilość wyświetlanego tekstu.
  • HighQuality – optymalizuje akapit pod kątem czytelności tekstu, w tym podziału wyrazów na sylaby (jeśli jest włączony). (powinno być domyślne dla wszystkich wartości, które nie są Balanced ani Simple).
  • Simple – podstawowa, szybka strategia. Jeśli ta opcja jest włączona, podział na sylaby jest stosowany tylko w przypadku słów, które nie mieszczą się w całym wierszu. Przydatne podczas edytowania tekstu, aby uniknąć zmiany 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 za pomocą strategii Balancedłamania wiersza:

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 strategią równomiernego rozmieszczania znaków końca wiersza oraz akapit sformatowany bez strategii. Akapit z strategią wyrównywania wierszy ma bardziej spójne długości wierszy niż domyślna.
Rysunek 2. Akapit sformatowany za pomocą Balanced strategii dzielenia wierszy (na górze) w porównaniu z akapitem sformatowanym bez strategii dzielenia wierszy.

Uwagi dotyczące CJK

LineBreak możesz też dostosować za pomocą interfejsów API StrictnessWordBreak, które zostały zaprojektowane specjalnie dla języków CJK. Efekty tych interfejsów API mogą nie być widoczne w językach innych niż CJK. Ogólnie reguły dotyczące dzielenia linii są definiowane na podstawie lokalizacji.

Strictness określa rygoryzm rozbijania wiersza z tymi właściwościami:

  • Default – domyślne reguły naruszenia dotyczące danego ustawienia regionalnego. Może odpowiadać wartości Normal lub Strict.
  • Loose – zasady najmniej restrykcyjne. Odpowiednie do krótkich linii.
  • Normal – najczęstsze reguły dotyczące dzielenia wyrazów.
  • Strict – najsurowsze reguły dotyczące dzielenia wyrazów.

WordBreak określa, jak w słowie powinny być wstawiane znaki końca wiersza. Właściwości:

  • Default – domyślne reguły naruszenia dotyczące danego ustawienia regionalnego.
  • Phrase – podział wiersza jest oparty na wyrażeniach.

Ten fragment kodu używa w przypadku tekstu japońskiego ustawień Strict (rygor) i Phrase (podział na słowa):

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 rygoryzmu i podziału wyrazów w porównaniu z tekstem domyślnym.
Rysunek 3. Tekst sformatowany za pomocą ustawień StrictnessWordBreak (góra) w porównaniu z tekstem sformatowanym tylko za pomocą LineBreak.Heading (dół).

Przecinek w tekście podzielonym na linie

Interfejs API Hyphens umożliwia dodanie do aplikacji obsługi dzielenia wyrazów. Dzielenie wyrazów polega na wstawianiu znaku interpunkcyjnego w postaci myślnika, aby wskazać, że wyraz jest podzielony na 2 wiersze tekstu. Gdy ta opcja jest włączona, w odpowiednich miejscach w słowie dodawane są łamań.

Domyślnie dzielenie wyrazów nie jest włączone. Aby włączyć dzielenie wyrazów, dodaj parametr Hyphens.Auto 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 włączonego dzielenia wyrazów i akapit z włączonym dzieleniem wyrazów.
  Gdy włączysz dzielenie wyrazów, słowo zostanie podzielone na sylaby i wydrukowane na 2 wierszach.
Rysunek 4. Akapit bez włączonej łamanej linii (u góry) i akapit z włączoną łamaną linią (u dołu).

Po włączeniu podział wyrazów występuje tylko w tych warunkach:

  • Słowo nie mieści się w wierszu. Jeśli używasz strategii Simple, podział na wiersze następuje tylko wtedy, gdy wiersz jest krótszy niż jedno słowo.
  • Na urządzeniu jest ustawiony odpowiedni język, a odpowiednie dzielenie wyrazów jest określane za pomocą słowników obecnych w systemie.