Menangani input pengguna

TextField memungkinkan pengguna memasukkan dan mengubah teks. Halaman ini menjelaskan cara mengimplementasikan TextField, menata gaya input TextField, dan mengonfigurasi opsi TextField lainnya, seperti opsi keyboard dan mengubah input pengguna secara visual.

Pilih penerapan TextField

Ada dua tingkat penerapan TextField:

  1. TextField adalah penerapan Desain Material. Sebaiknya pilih implementasi 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 berisi kata

@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.

Gaya TextField

TextField dan BasicTextField berbagi banyak parameter umum untuk menyesuaikannya. Daftar lengkap untuk TextField tersedia di kode sumber TextField. 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 banyak baris, dengan dua baris yang dapat diedit plus label

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

Input gaya dengan Brush API

Anda dapat menggunakan Brush API untuk penataan gaya yang lebih canggih di TextField. Bagian berikut menjelaskan cara menggunakan Kuas untuk menambahkan gradien berwarna ke input TextField.

Untuk informasi selengkapnya tentang cara menggunakan Brush API untuk menata gaya teks, lihat Mengaktifkan gaya visual lanjutan dengan Brush API.

Mengimplementasikan gradien warna menggunakan TextStyle

Untuk menerapkan gradien berwarna saat Anda mengetik dalam TextField, tetapkan kuas pilihan sebagai TextStyle untuk TextField Anda. Dalam contoh ini, kami menggunakan kuas bawaan dengan linearGradient untuk melihat efek gradien pelangi saat teks diketik ke dalam TextField.

var text by remember { mutableStateOf("") }
val brush = remember {
    Brush.linearGradient(
        colors = rainbowColors
    )
}
TextField(
    value = text, onValueChange = { text = it }, textStyle = TextStyle(brush = brush)
)

Menggunakan buildAnnotatedString dan SpanStyle, bersama dengan linearGradient, untuk menyesuaikan hanya sepotong teks.
Gambar 3. Menggunakan buildAnnotatedString dan SpanStyle, beserta linearGradient, untuk menyesuaikan hanya sebagian teks.

Menyetel 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

Input format

TextField memungkinkan Anda menyetel VisualTransformation pada 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 VisualTransformationSamples kode sumber.

Bersihkan input

Tugas umum saat mengedit teks adalah menghapus karakter di depan, atau mengubah string input setiap kali berubah.

Sebagai model, Anda harus mengasumsikan bahwa keyboard dapat membuat edit yang arbitrer dan besar untuk setiap onValueChange. Ini dapat terjadi, misalnya, jika pengguna menggunakan koreksi otomatis, mengganti kata dengan emoji, atau fitur pengeditan cerdas lainnya. Untuk menangani ini dengan benar, tulis logika transformasi dengan asumsi bahwa teks saat ini yang diteruskan ke onValueChange tidak terkait dengan nilai sebelumnya atau berikutnya yang akan diteruskan ke onValueChange.

Untuk menerapkan kolom teks yang melarang nol di depan, Anda dapat melakukannya dengan menghapus semua nol di depan pada setiap perubahan nilai.

@Composable
fun NoLeadingZeroes() {
    var input by rememberSaveable { mutableStateOf("") }
    TextField(
        value = input,
        onValueChange = { newText ->
            input = newText.trimStart { it == '0' }
        }
    )
}

Untuk mengontrol posisi kursor saat membersihkan teks, gunakan overload TextFieldValue dari TextField sebagai bagian dari status.

Praktik terbaik dengan negara bagian

Berikut adalah serangkaian praktik terbaik untuk menentukan dan memperbarui status TextField guna mencegah masalah input di aplikasi Anda.

  • Gunakan MutableState untuk mewakili status TextField: Hindari penggunaan aliran reaktif seperti StateFlow untuk mewakili status TextField, karena struktur ini dapat menyebabkan penundaan asinkron.

class SignUpViewModel : ViewModel() {

    var username by mutableStateOf("")
        private set

    /* ... */
}

  • Hindari penundaan untuk memperbarui status: Saat Anda memanggil onValueChange, perbarui TextField secara sinkron dan segera:

// SignUpViewModel.kt

class SignUpViewModel(private val userRepository: UserRepository) : ViewModel() {

    var username by mutableStateOf("")
        private set

    fun updateUsername(input: String) {
        username = input
    }
}

// SignUpScreen.kt

@Composable
fun SignUpScreen(/*...*/) {

    OutlinedTextField(
        value = viewModel.username,
        onValueChange = { username -> viewModel.updateUsername(username) }
        /*...*/
    )
}

  • Tempat menentukan status: Jika status TextField memerlukan validasi logika bisnis saat Anda mengetik, status tersebut sudah benar untuk diangkat ke ViewModel. Jika tidak, Anda dapat menggunakan composable atau class holder status sebagai sumber kebenaran. Untuk mempelajari lebih lanjut tempat untuk mengangkat status, lihat dokumentasi pengangkatan status.