Gaya paragraf

Halaman ini menjelaskan cara menata gaya teks untuk paragraf. Untuk menetapkan gaya tingkat paragraf, Anda dapat mengonfigurasi parameter seperti textAlign dan lineHeight atau menentukan ParagraphStyle Anda sendiri.

Menetapkan perataan teks

Parameter textAlign memungkinkan Anda menetapkan perataan horizontal teks dalam area permukaan composable Text.

Secara default, Text akan memilih perataan teks alami, tergantung nilai kontennya:

  • Tepi kiri penampung Text untuk alfabet kiri ke kanan seperti Latin, Cyrillic (Sirilik), atau Hangul
  • Tepi kanan penampung Text untuk alfabet kanan ke kiri seperti bahasa Arab atau Ibrani

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

Kata-kata

Jika Anda ingin menetapkan perataan teks untuk composable Text secara manual, lebih baik gunakan TextAlign.Start dan TextAlign.End, bukan TextAlign.Left dan TextAlign.Right, karena penyelesaian ke tepi kanan composable Text bergantung pada orientasi teks bahasa yang dipilih. Misalnya, TextAlign.End meratakan ke sisi kanan untuk teks bahasa Prancis dan ke sisi kiri untuk teks bahasa Arab, tetapi TextAlign.Right akan meratakan ke sisi kanan, alfabet mana pun yang digunakan.

Menambahkan beberapa gaya dalam satu paragraf

Untuk menambahkan beberapa gaya dalam paragraf, Anda dapat menggunakan ParagraphStyle dalam AnnotatedString, yang dapat dianotasi dengan gaya anotasi arbitrer. Setelah sebagian teks Anda ditandai dengan ParagraphStyle, bagian tersebut akan dipisahkan dari teks lainnya seolah-olah memiliki feed baris di awal dan akhir.

Untuk informasi selengkapnya tentang cara menambahkan beberapa gaya dalam teks, lihat Menambahkan beberapa gaya dalam teks.

AnnotatedString memiliki builder yang aman agar lebih mudah dibuat: buildAnnotatedString. Cuplikan berikut menggunakan buildAnnotatedString untuk menetapkan 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")
            }
        }
    )
}

Tiga paragraf dalam tiga gaya yang berbeda: Biru, merah dan tebal, dan hitam biasa

Menyesuaikan tinggi baris dan padding

includeFontPadding adalah properti lama yang menambahkan padding tambahan berdasarkan metrik font di bagian atas baris pertama dan bagian bawah baris terakhir teks. Mulai dari Compose BOM versi 2024.01.01, includeFontPadding ditetapkan ke false secara default, yang membuat tata letak teks default lebih selaras dengan alat desain umum.

Kemampuan untuk mengonfigurasi lineHeight bukanlah hal yang baru, melainkan telah tersedia sejak Android Q. Anda dapat mengonfigurasi lineHeight untuk Text menggunakan parameter lineHeight, yang mendistribusikan tinggi baris di setiap baris teks. Anda kemudian dapat menggunakan LineHeightStyle API baru untuk mengonfigurasi lebih lanjut perataan teks ini dalam ruang, dan menghapus spasi kosong.

Anda mungkin ingin menyesuaikan lineHeight menggunakan unit teks “em” (ukuran font relatif) bukan “sp” (piksel yang diskalakan) untuk presisi yang lebih baik. Untuk informasi selengkapnya tentang memilih unit teks yang sesuai, lihat TextUnit.

Gambar yang menampilkan lineHeight sebagai pengukuran berdasarkan baris yang berada tepat di atas dan di bawahnya.
Gambar 1. Gunakan Alignment dan Trim untuk menyesuaikan teks dalam lineHeight yang ditetapkan, dan memangkas ruang tambahan jika diperlukan.

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

Selain menyesuaikan lineHeight, Anda kini dapat memusatkan dan menata gaya teks lebih lanjut menggunakan konfigurasi dengan LineHeightStyle API eksperimental: LineHeightStyle.Alignment dan LineHeightStyle.Trim (includeFontPadding harus disetel ke false agar Trim berfungsi). Alignment dan Trim menggunakan spasi terukur di antara baris teks untuk mendistribusikannya dengan lebih tepat ke semua baris–termasuk satu baris teks dan baris atas blok teks.

LineHeightStyle.Alignment menentukan cara perataan garis pada ruang yang diberikan oleh tinggi baris. Dalam setiap baris, Anda dapat meratakan teks ke bagian atas, bawah, tengah, atau secara proporsional. LineHeightStyle.Trim kemudian memungkinkan Anda meninggalkan atau menghapus ruang tambahan di bagian atas baris pertama dan bawah baris terakhir teks Anda, yang dihasilkan dari penyesuaian lineHeight dan Alignment. Contoh berikut menunjukkan tampilan teks multibaris dengan berbagai konfigurasi LineHeightStyle.Trim saat perataan dipusatkan (LineHeightStyle.Alignment.Center).

Gambar yang menunjukkan LineHeightStyle.Trim.None Gambar yang menunjukkan LineHeightStyle.Trim.Both
LineHeightStyle.Trim.None LineHeightStyle.Trim.Both
Gambar yang menunjukkan LineHeightStyle.Trim.FirstLineTop Gambar yang menunjukkan LineHeightStyle.Trim.LastLineBottom
LineHeightStyle.Trim.FirstLineTop LineHeightStyle.Trim.LastLineBottom

Lihat postingan blog Memperbaiki Padding Font di Teks Compose untuk mempelajari lebih lanjut konteks perubahan ini, cara kerja includeFontPadding dalam sistem View, dan perubahan yang dibuat untuk Compose serta LineHeightStyle API baru.

Menyisipkan jeda baris

LineBreak API menentukan kriteria pemisahan teks di beberapa baris. Anda dapat menentukan jenis pemisahan baris yang diinginkan di blok TextStyle dari composable Text. Jenis pemisahan baris preset meliputi:

  • Simple — Pemisahan baris dasar yang cepat. Direkomendasikan untuk kolom input teks.
  • Heading — Pemisahan baris dengan aturan pemisahan yang lebih longgar. Direkomendasikan untuk teks pendek, seperti judul.
  • Paragraph — Pemisahan baris yang lebih lambat dan berkualitas lebih tinggi untuk meningkatkan keterbacaan. Direkomendasikan untuk teks dalam jumlah yang lebih besar, seperti paragraf.

Cuplikan berikut menggunakan Simple dan Paragraph untuk menentukan perilaku pemisahan baris pada blok teks yang panjang:

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 teks yang menunjukkan strategi pemisahan baris sederhana dibandingkan dengan blok
  teks dengan strategi pemisahan yang dioptimalkan untuk paragraf. Blok teks dengan strategi pemisahan baris sederhana memiliki variabilitas yang lebih besar dalam panjang baris.
Gambar 1. Blok teks dengan strategi pemisahan baris sederhana (atas) versus blok teks dengan pemisahan baris yang dioptimalkan untuk paragraf (bawah).

Pada output di atas, perhatikan bahwa perilaku pemisahan baris Paragraph menghasilkan hasil yang lebih seimbang secara visual daripada pemisahan baris Simple.

Menyesuaikan jeda baris

Anda juga dapat membuat konfigurasi LineBreak sendiri dengan parameter Strategy. Strategy dapat berupa salah satu dari hal berikut:

  • Balanced — Mencoba menyeimbangkan panjang baris teks, juga menerapkan pemisahan kata otomatis jika diaktifkan. Direkomendasikan untuk layar kecil, seperti smartwatch, untuk memaksimalkan jumlah teks yang ditampilkan.
  • HighQuality — Mengoptimalkan paragraf untuk teks yang lebih mudah dibaca, termasuk pemisahan kata jika diaktifkan. (Harus berupa default untuk semua yang bukan Balanced atau Simple.)
  • Simple — strategi dasar dan cepat. Jika diaktifkan, tanda hubung hanya dilakukan untuk kata yang tidak muat di seluruh baris. Berguna untuk mengedit teks agar tidak mengubah posisi saat mengetik.

Cuplikan berikut menunjukkan perbedaan antara paragraf dengan setelan default dan paragraf yang dioptimalkan untuk layar kecil dengan strategi pemisahan baris 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
            )
        }
    )
)

Paragraf dengan strategi pemisahan baris yang seimbang dan paragraf
  yang diformat tanpa strategi. Paragraf dengan strategi pemisahan baris yang seimbang
  memiliki panjang baris yang lebih konsisten daripada default.
Gambar 2. Paragraf yang diformat dengan strategi pemisahan baris Balanced (atas) versus paragraf yang diformat tanpa strategi pemisahan baris.

Pertimbangan CJK

Anda juga dapat menyesuaikan LineBreak dengan API Strictness dan WordBreak, yang dirancang khusus untuk bahasa CJK. Anda mungkin tidak selalu melihat efek API ini dalam bahasa non-CJK. Secara keseluruhan, aturan pemisahan baris ditentukan berdasarkan lokalitas.

Strictness menjelaskan ketelitian pemutusan baris dengan properti berikut:

  • Default — Aturan pemisahan default untuk lokalitas. Mungkin sesuai dengan Normal atau Strict.
  • Loose — Aturan yang paling longgar. Cocok untuk baris pendek.
  • Normal — Aturan paling umum untuk pemutusan baris.
  • Strict — Aturan paling ketat untuk pemutusan baris.

WordBreak menentukan cara penyisipan baris baru dalam kata dengan properti berikut:

  • Default — Aturan pemisahan default untuk lokalitas.
  • Phrase — Pemisahan baris didasarkan pada frasa.

Cuplikan berikut menggunakan ketegasan Strict dan setelan pemisahan kata Phrase untuk teks bahasa Jepang:

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

Teks Jepang dengan setelan Ketegasan dan Pemisah Kata versus teks default.
Gambar 3. Teks yang diformat dengan setelan Strictness dan WordBreak (atas) dibandingkan dengan teks yang hanya diformat dengan LineBreak.Heading (bawah).

Menambahkan tanda hubung pada teks yang terpisah di beberapa baris

Hyphens API memungkinkan Anda menambahkan dukungan tanda hubung ke aplikasi. Tanda hubung mengacu pada penyisipan tanda baca seperti tanda hubung untuk menunjukkan bahwa kata dibagi di seluruh baris teks. Jika diaktifkan, tanda hubung akan ditambahkan di antara suku kata kata pada titik hubung yang sesuai.

Secara default, tanda hubung tidak diaktifkan. Untuk mengaktifkan tanda hubung, tambahkan Hyphens.Auto sebagai parameter dalam blok 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
                )
            )
        }
    )
)

Paragraf tanpa tanda hubung yang diaktifkan dan paragraf dengan tanda hubung yang diaktifkan.
  Jika tanda hubung diaktifkan, kata akan diberi tanda hubung dan dibagi menjadi dua baris.
Gambar 4. Paragraf tanpa tanda hubung yang diaktifkan (atas) versus paragraf dengan tanda hubung yang diaktifkan (bawah).

Jika diaktifkan, tanda hubung hanya akan muncul dalam kondisi berikut:

  • Kata tidak muat dalam satu baris. Jika Anda menggunakan strategi pemisahan baris Simple, penghilangan tanda hubung pada kata hanya terjadi jika baris lebih pendek daripada satu kata.
  • Lokalitas yang sesuai ditetapkan di perangkat Anda, karena tanda hubung yang sesuai ditentukan menggunakan kamus yang ada di sistem.