Teks dalam Compose

Teks adalah bagian utama dari setiap UI, dan Jetpack Compose memudahkan untuk menampilkan atau menulis teks. Compose memanfaatkan komposisi elemen penyusunnya, yang berarti Anda tidak perlu menimpa properti dan metode atau memperluas class besar agar memiliki desain dan logika spesifik composable seperti yang Anda inginkan.

Sebagai dasarnya, Compose menyediakan BasicText dan BasicTextField yang merupakan barebone untuk menampilkan teks dan menangani input pengguna. Pada level yang lebih tinggi, Compose menyediakan Text dan TextField, yang merupakan composable mengikuti panduan Desain Material. Sebaiknya gunakan fitur tersebut karena fitur memiliki tampilan dan nuansa yang tepat untuk pengguna di Android, dan menyertakan opsi lain untuk menyederhanakan penyesuaian tanpa harus menulis banyak kode.

Menampilkan teks

Cara paling dasar untuk menampilkan teks adalah dengan menggunakan composable Text dengan String sebagai argumen:

@Composable
fun SimpleText() {
  Text("Hello World")
}

Kata "Hello World" (Halo Dunia) dalam teks hitam biasa

Menampilkan teks dari resource

Sebaiknya gunakan resource string, bukan nilai Text hardcode, karena Anda dapat berbagi string yang sama dengan Tampilan Android serta menyiapkan aplikasi untuk internasionalisasi:

@Composable
fun StringResourceText() {
  Text(stringResource(R.string.hello_world))
}

Menata gaya teks

Composable Text memiliki beberapa parameter opsional untuk mengatur gaya kontennya. Di bawah ini, kami telah mencantumkan parameter yang mencakup kasus penggunaan paling umum dengan teks. Untuk melihat semua parameter Text, sebaiknya lihat Kode sumber Teks Compose.

Setiap kali Anda menetapkan salah satu parameter ini, Anda menerapkan gaya ke seluruh nilai teks. Jika Anda perlu menerapkan beberapa gaya dalam baris atau paragraf yang sama, lihat bagian beberapa gaya inline.

Mengubah warna teks

@Composable
fun BlueText() {
  Text("Hello World", color = Color.Blue)
}

Kata "Hello World" (Halo Dunia) dalam teks berwarna biru

Mengubah ukuran teks

@Composable
fun BigText() {
  Text("Hello World", fontSize = 30.sp)
}

Kata-kata "Hello World" (Halo Dunia) dalam ukuran yang lebih besar

Memiringkan teks

@Composable
fun ItalicText() {
  Text("Hello World", fontStyle = FontStyle.Italic)
}

Kata-kata "Hello World" (Halo Dunia) dalam huruf miring

Menebalkan teks

@Composable
fun BoldText() {
    Text("Hello World", fontWeight = FontWeight.Bold)
}

Kata-kata "Hello World" (Halo Dunia) dalam huruf cetak tebal

Perataan teks

Parameter textAlign memungkinkan untuk menetapkan perataan 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
@Preview(showBackground = true)
@Composable
fun CenterText() {
    Text("Hello World", textAlign = TextAlign.Center,
                modifier = Modifier.width(150.dp))
}

Kata "Hello World" (Halo Dunia) berada di tengah elemen penampungnya

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 me-resolve 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.

Menangani font

Text memiliki parameter fontFamily untuk mengizinkan penyetelan font yang digunakan dalam composable. Secara default, jenis font serif, sans-serif, monospace, dan kursif disertakan:

@Composable
fun DifferentFonts() {
    Column {
        Text("Hello World", fontFamily = FontFamily.Serif)
        Text("Hello World", fontFamily = FontFamily.SansSerif)
    }
}

Kata-kata "Hello World" (Halo Dunia) dalam dua font yang berbeda, dengan dan tanpa serif

Anda dapat menggunakan atribut fontFamily untuk menggunakan font dan jenis huruf kustom yang ditentukan di folder res/fonts:

Penggambaran grafis dari res > folder font di lingkungan pengembangan

Contoh ini menunjukkan cara menentukan fontFamily berdasarkan file font tersebut:

val firaSansFamily = FontFamily(
        Font(R.font.firasans_light, FontWeight.Light),
        Font(R.font.firasans_regular, FontWeight.Normal),
        Font(R.font.firasans_italic, FontWeight.Normal, FontStyle.Italic),
        Font(R.font.firasans_medium, FontWeight.Medium),
        Font(R.font.firasans_bold, FontWeight.Bold)
)

Terakhir, Anda dapat meneruskan fontFamily ini ke composable Text. Karena fontFamily dapat menyertakan bobot yang berbeda, Anda dapat menyetel fontWeight secara manual untuk memilih bobot yang tepat untuk teks Anda:

Column {
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Light)
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Normal)
    Text(
        ..., fontFamily = firaSansFamily, fontWeight = FontWeight.Normal,
        fontStyle = FontStyle.Italic
    )
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Medium)
    Text(..., fontFamily = firaSansFamily, fontWeight = FontWeight.Bold)
}

Kata-kata "Hello World" (Halo Dunia) dalam beberapa jenis bobot dan gaya

Untuk mempelajari cara menyetel tipografi di seluruh aplikasi, lihat dokumentasi tema.

Berbagai gaya dalam satu teks

Untuk menyetel gaya berbeda dalam composable Text, Anda harus menggunakan AnnotatedString, string yang dapat dianotasi dengan gaya anotasi arbitrer.

AnnotatedString adalah class data yang berisi:

  • Nilai Text
  • List dari SpanStyleRange, setara dengan gaya inline dengan rentang posisi dalam nilai teks
  • List dari ParagraphStyleRange, menentukan perataan teks, arah teks, tinggi baris, dan gaya indentasi teks

TextStyle digunakan untuk composable Text, sedangkan SpanStyle dan ParagraphStyle digunakan untuk AnnotatedString.

Perbedaan antara SpanStyle dan ParagraphStyle adalah bahwa ParagraphStyle dapat diterapkan ke seluruh paragraf, sedangkan SpanStyle dapat diterapkan pada tingkat karakter. Setelah sebagian teks ditandai dengan ParagraphStyle, bagian tersebut akan dipisahkan dari bagian lainnya seolah-olah memiliki feed baris di awal dan akhir.

AnnotatedString memiliki builder yang aman untuk mempermudah membuatnya:

@Composable
fun MultipleStylesInText() {
    Text(
        buildAnnotatedString {
            withStyle(style = SpanStyle(color = Color.Blue)) {
                append("H")
            }
            append("ello ")

            withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Red)) {
                append("W")
            }
            append("orld")
        }
    )
}

Kata-kata "Hello World" (Halo Dunia) dengan beberapa perubahan gaya inline; H berwarna biru, dan W berwarna merah dan tebal

Kita dapat menyetel gaya paragraf dengan cara yang sama:

@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

Jumlah baris maksimum

Untuk membatasi jumlah baris yang terlihat di composable Text, setel parameter maxLines:

@Composable
fun LongText() {
    Text("hello ".repeat(50), maxLines = 2)
}

Teks panjang yang terpotong setelah dua baris

Text-overflow

Saat membatasi teks panjang, Anda mungkin ingin menunjukkan text overflow, yang hanya ditampilkan jika teks yang ditampilkan terpotong. Untuk melakukannya, setel parameter textOverflow:

@Composable
fun OverflowedText() {
    Text("Hello Compose ".repeat(50), maxLines = 2, overflow = TextOverflow.Ellipsis)
}

Teks panjang terpotong setelah tiga baris, dengan elipsis di bagian akhir

Tema

Untuk menggunakan tema aplikasi untuk penataan teks, lihat dokumentasi tema.

Interaksi pengguna

Jetpack Compose memungkinkan interaksi yang lebih mendetail di Text. Pemilihan teks kini lebih fleksibel dan dapat dilakukan di seluruh tata letak composable. Interaksi pengguna dalam teks berbeda dengan tata letak composable lainnya, karena Anda tidak dapat menambahkan pengubah ke bagian dari composable Text. Bagian ini menyoroti API yang berbeda untuk mengaktifkan interaksi pengguna.

Memilih teks

Secara default, composable tidak dapat dipilih, yang berarti pengguna secara default tidak dapat memilih dan menyalin teks dari aplikasi Anda. Untuk mengaktifkan pemilihan teks, Anda harus menggabungkan elemen teks Anda dengan composable SelectionContainer:

@Composable
fun SelectableText() {
    SelectionContainer {
        Text("This text is selectable")
    }
}

Teks singkat yang dipilih oleh pengguna.

Anda mungkin ingin menonaktifkan pilihan pada bagian tertentu dari area yang dapat dipilih. Untuk melakukannya, Anda harus menggabungkan bagian yang tidak dapat dipilih dengan composable DisableSelection:

@Composable
fun PartiallySelectableText() {
    SelectionContainer {
        Column {
            Text("This text is selectable")
            Text("This one too")
            Text("This one as well")
            DisableSelection {
                Text("But not this one")
                Text("Neither this one")
            }
            Text("But again, you can select this one")
            Text("And this one too")
        }
    }
}

Teks yang lebih panjang. Pengguna mencoba memilih seluruh bagian, tetapi karena dua baris telah menerapkan DisableSelection, mereka tidak dipilih.

Menyiapkan posisi klik pada teks

Untuk memproses klik pada Text, Anda dapat menambahkan pengubah clickable. Namun, jika Anda ingin menyiapkan posisi klik dalam composable Text, dan Anda memiliki tindakan yang berbeda berdasarkan bagian teks yang berbeda, Anda harus menggunakan ClickableText sebagai gantinya:

@Composable
fun SimpleClickableText() {
    ClickableText(
        text = AnnotatedString("Click Me"),
        onClick = { offset ->
            Log.d("ClickableText", "$offset -th character is clicked.")
        }
    )
}

Mengklik dengan anotasi

Saat pengguna mengklik composable Text, Anda mungkin ingin melampirkan informasi tambahan ke bagian nilai Text, seperti URL yang terkait dengan kata tertentu yang akan dibuka di browser sebagai contoh. Untuk melakukannya, Anda harus melampirkan anotasi, yang menggunakan tag (String), item (String), dan rentang teks sebagai parameter. Dari AnnotatedString, anotasi ini dapat difilter dengan tag atau rentang teksnya. Berikut contohnya:

@Composable
fun AnnotatedClickableText() {
    val annotatedText = buildAnnotatedString {
        append("Click ")

        // We attach this *URL* annotation to the following content
        // until `pop()` is called
        pushStringAnnotation(tag = "URL",
                             annotation = "https://developer.android.com")
        withStyle(style = SpanStyle(color = Color.Blue,
                                    fontWeight = FontWeight.Bold)) {
            append("here")
        }

        pop()
    }

    ClickableText(
        text = annotatedText,
        onClick = { offset ->
            // We check if there is an *URL* annotation attached to the text
            // at the clicked position
            annotatedText.getStringAnnotations(tag = "URL", start = offset,
                                                    end = offset)
                .firstOrNull()?.let { annotation ->
                    // If yes, we log its value
                    Log.d("Clicked URL", annotation.item)
                }
        }
    )
}

Memasukkan dan mengubah teks

TextField memungkinkan pengguna memasukkan dan mengubah teks. Ada dua tingkat implementasi TextField:

  1. TextField adalah penerapan Desain Material. Sebaiknya pilih penerapan ini karena mengikuti panduan desain material:
    • Gaya default adalah filled
    • OutlinedTextField adalah versi gaya outline
  2. BasicTextField memungkinkan pengguna mengedit teks melalui keyboard hardware atau software, tetapi tidak memberikan dekorasi seperti petunjuk atau placeholder.
@Composable
fun SimpleFilledTextFieldSample() {
    var text by remember { mutableStateOf("Hello") }

    TextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

Kolom teks yang dapat diedit yang berisi kata "Halo". Kolom ini memiliki label "label" yang tidak dapat diedit.

@Composable
fun SimpleOutlinedTextFieldSample() {
    var text by remember { mutableStateOf("") }

    OutlinedTextField(
        value = text,
        onValueChange = { text = it },
        label = { Text("Label") }
    )
}

Kolom teks yang dapat diedit, dengan batas dan label berwarna ungu.

Penataan Gaya TeksField

TextField dan BasicTextField berbagi banyak parameter umum untuk menyesuaikannya. Daftar lengkap untuk TextField tersedia di kode sumberTextField. Berikut adalah daftar tidak lengkap beberapa parameter yang berguna:

  • singleLine
  • maxLines
  • textStyle
@Composable
fun StyledTextField() {
    var value by remember { mutableStateOf("Hello\nWorld\nInvisible") }

    TextField(
        value = value,
        onValueChange = { value = it },
        label = { Text("Enter text") },
        maxLines = 2,
        textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
        modifier = Modifier.padding(20.dp)
    )
}

TextField multigaris, dengan dua baris yang dapat diedit plus label

Sebaiknya gunakan TextField daripada BasicTextField saat desain Anda memanggil Material TextField atau OutlineTextField. Namun, BasicTextField harus digunakan saat mem-build desain yang tidak memerlukan dekorasi dari spesifikasi Material.

Opsi keyboard

TextField memungkinkan Anda menyetel opsi konfigurasi keyboard, seperti tata letak keyboard, atau mengaktifkan koreksi otomatis jika didukung oleh keyboard. Beberapa opsi mungkin tidak dijamin jika keyboard virtual tidak sesuai dengan opsi yang disediakan di sini. Berikut adalah daftar opsi keyboard yang didukung:

  • capitalization
  • autoCorrect
  • keyboardType
  • imeAction

Format

TextField memungkinkan Anda menyetel pemformatan visual ke nilai input, seperti mengganti karakter dengan * untuk sandi, atau memasukkan tanda hubung setiap 4 digit untuk nomor kartu kredit:

@Composable
fun PasswordTextField() {
    var password by rememberSaveable { mutableStateOf("") }

    TextField(
        value = password,
        onValueChange = { password = it },
        label = { Text("Enter password") },
        visualTransformation = PasswordVisualTransformation(),
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
    )
}

Kolom entri teks sandi, dengan teks yang disembunyikan

Contoh lainnya tersedia di kode sumber VisualTransformSamples.