Styl akapitu

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

Ustawianie wyrównania tekstu

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

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

  • Lewa krawędź kontenera Text dla alfabetów pisanych od lewej do prawej, takich jak łaciński, cyrylica lub 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. Przykład: TextAlign.End wyrównuje się do prawej strony w przypadku tekstu w języku francuskim i do lewej dla tekstu arabskiego, ale TextAlign.Right jest wyrównany do prawej strony w każdym przypadku 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 o dowolnym stylu. Gdy część tekstu zostanie oznaczona symbolem ParagraphStyle, zostanie ona oddzielona od reszty tekstu tak, jakby miała spacje na początku i na końcu.

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

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

dostosować wysokość wiersza i dopełnienie;

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. 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 ze standardowymi narzędziami do projektowania.

Możliwość konfigurowania lineHeight nie jest nowa – została już dostępna od Androida Q. Możesz skonfigurować usługę lineHeight dla domeny Text za pomocą lineHeight, który rozdziela wysokość wiersza w każdym wierszu argumentu tekstu. Następnie możesz użyć nowej wersji LineHeightStyle API, aby dokładniej skonfigurować wyrównanie tekstu w obrębie spacji i usunięcie odstępów.

Aby zwiększyć dokładność, możesz dostosować wartość lineHeight za pomocą jednostki tekstowej „em” (względny rozmiar czcionki) zamiast „sp” (przeskalowane piksele). Więcej informacji na temat: wybierając odpowiednią jednostkę tekstową, zapoznaj się z sekcją 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ównaj i przytnij, aby dostosować tekst w ramach zestawu lineHeight, a w razie potrzeby przytnij nadmiar wolnego miejsca.

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 z LineHeightStyle eksperymentalnym interfejsem API: LineHeightStyle.Alignment i LineHeightStyle.Trim (aby funkcja Trim działała, includeFontPadding musi być ustawiony na false). Wyrównanie i przycinanie korzystają z pomiaru odstępu między wierszami tekstu, aby odpowiednio rozmieścić go we wszystkich wierszach, w tym w jednym wierszu i górnym wierszem bloku tekstu.

LineHeightStyle.Alignment określa sposób wyrównania wiersza w przestrzeni określonej przez wysokość wiersza. W każdym wierszu możesz wyrównać tekst do góry, na dole, do środka lub proporcjonalnie. LineHeightStyle.Trim następnie umożliwi Ci , aby opuścić lub usunąć dodatkową przestrzeń u góry pierwszego wiersza i na dole ostatni wiersz tekstu wygenerowany na podstawie dowolnych elementów lineHeight i wyrównania korekty. Poniższe przykłady pokazują, jak tekst wielowierszowy wygląda w przypadku funkcji różne konfiguracje LineHeightStyle.Trim przy wyśrodkowaniu (LineHeightStyle.Alignment.Center).

Obraz pokazujący element LineHeightStyle.Przytnij.None Obraz przedstawiają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

Więcej informacji o kontekście tej zmiany, działaniu funkcji includeFontPadding w systemie View oraz zmianach wprowadzonych w komponencie Compose i nowych interfejsach API LineHeightStyle znajdziesz w poście na blogu Poprawki w odstępach między znakami 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 przełamania wiersza chcesz zastosować. Dostępne wstępnie typy dzielenia wiersza:

  • Simple – szybkie, proste łamanie linii. Zalecane w przypadku pól tekstowych.
  • Heading – łamanie wiersza z luźniejszymi regułami łamania. Zalecane w przypadku krótkich filmów tekst, np. tytuły.
  • 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 tekstowy, który przedstawia prostą strategię przerywania wierszy oraz tekst
  ze strategią podziału na strony zoptymalizowaną pod kątem akapitów. Blok tekstowy z prostymi
strategia przerywania wierszy ma większą zmienność w długości wierszy.
Rysunek 1. Blok tekstu z prostą strategią dzielenia wierszy (u góry) w porównaniu z blokiem tekstu z optymalizacją dzielenia wierszy w paragrafach (u dołu).

W powyższym wyjściu widać, że zachowanie Paragraph w przypadku przełamania 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óbuje zrównoważyć długość wierszy tekstu. Stosowane są również automatyczne łączniki, jeśli jest włączone. Zalecane na małych ekranach, np. na zegarkach, aby zmaksymalizować ilość wyświetlanego tekstu.
  • HighQuality – optymalizuje akapit, aby zwiększyć czytelność tekstu, w tym: łącznik (jeśli jest włączony). (powinno być domyślne dla wszystkich wartości innych niż Balanced lub Simple).
  • Simple – podstawowa, szybka strategia. Jeśli ta opcja jest włączona, podział wyrazów jest stosowany tylko w przypadku wyrazó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 przerywanym wierszem
  ma bardziej stabilną długość wierszy niż domyślna.
Rysunek 2. Akapit sformatowany zgodnie ze strategią podziału wierszy Balanced (u góry) w odróżnieniu od akapitu sformatowanego 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 do obsługi języków CJK. Efekty tych interfejsów API mogą nie być widoczne w językach innych niż CJK. Ogólnie reguły dzielenia linii są definiowane na podstawie lokalizacji.

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

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

WordBreak określa, jak w słowie mają 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 Ścisłości i Podziału słów w porównaniu z tekstem domyślnym.
Rysunek 3. Tekst sformatowany z użyciem ustawień Strictness i WordBreak (u góry) a tekst sformatowany tylko z użyciem LineBreak.Heading (u dołu).

Dziel tekst między wierszami

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, łącznik jest dodawany między sylabariacie słowa w odpowiednich miejscach łącznika;

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 łącznik jest włączony, wyraz zostaje dzielony na 2 wiersze.
Rysunek 4. Akapit bez włączonej łamanej linii (u góry) i akapit z włączoną łamaną linią (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żywasz strategii Simple, podział na wiersze następuje tylko wtedy, gdy wiersz jest krótszy niż pojedyncze słowo.
  • Na urządzeniu ustawiony jest odpowiedni region, a odpowiednie dzielenie wyrazów jest określane za pomocą słowników obecnych w systemie.