Mengonfigurasi kolom teks

TextField memungkinkan pengguna memasukkan dan mengubah teks. Ada dua jenis kolom teks yang dapat Anda gunakan: kolom teks berbasis status dan kolom teks berbasis nilai. Pilih jenis yang kontennya ingin Anda tampilkan:

Sebaiknya gunakan kolom teks berbasis status, karena menyediakan pendekatan yang lebih lengkap dan andal untuk mengelola status TextField. Tabel berikut menjelaskan perbedaan antara jenis kolom teks ini, dan menyertakan keunggulan utama yang ditawarkan kolom teks berbasis status:

Fitur

Kolom teks berbasis nilai

Kolom teks berbasis status

Manfaat berbasis status

Pengelolaan status

Memperbarui status kolom teks dengan callback onValueChange. Anda bertanggung jawab untuk memperbarui value dalam status Anda sendiri berdasarkan perubahan yang dilaporkan oleh onValueChange.

Menggunakan objek TextFieldState secara eksplisit untuk mengelola status input teks (nilai, pilihan, komposisi). Status ini dapat diingat dan dibagikan.

  • Callback onValueChange telah dihapus, sehingga Anda tidak dapat memperkenalkan perilaku asinkron.
  • Status tetap ada selama rekomposisi, konfigurasi, dan penghentian proses.

Transformasi visual

Menggunakan VisualTransformation untuk mengubah tampilan teks yang ditampilkan. Hal ini biasanya menangani pemformatan input dan output dalam satu langkah.

Menggunakan InputTransformation untuk mengubah input pengguna sebelum di-commit ke status, dan OutputTransformation untuk memformat konten kolom teks tanpa mengubah data status yang mendasarinya.

  • Anda tidak perlu lagi menyediakan pemetaan offset antara teks mentah asli dan teks yang ditransformasi dengan OutputTransformation.

Batas baris

Menerima singleLine: Boolean, maxLines: Int, dan minLines: Int untuk mengontrol jumlah baris.

Menggunakan lineLimits: TextFieldLineLimits untuk mengonfigurasi jumlah baris minimum dan maksimum yang dapat ditempati kolom teks.

  • Menghapus ambiguitas saat mengonfigurasi batas baris dengan memberikan parameter lineLimits dari jenis TextFieldLineLimits.

Kolom teks aman

T/A

SecureTextField adalah composable yang dibuat di atas kolom teks berbasis status untuk menulis kolom sandi.

  • Memungkinkan Anda mengoptimalkan keamanan di balik layar, dan dilengkapi dengan UI standar dengan textObfuscationMode.

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

Memilih penerapan TextField

Ada dua tingkat penerapan 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.

TextField(
    state = rememberTextFieldState(initialText = "Hello"),
    label = { Text("Label") }
)

Kolom teks yang dapat diedit yang berisi kata

OutlinedTextField(
    state = rememberTextFieldState(),
    label = { Text("Label") }
)

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

Gaya TextField

TextField dan BasicTextField memiliki banyak parameter umum untuk penyesuaian. Daftar lengkap untuk TextField tersedia di kode sumber TextField. Berikut adalah daftar tidak lengkap beberapa parameter yang berguna:

  • textStyle
  • lineLimits

TextField(
    state = rememberTextFieldState("Hello\nWorld\nInvisible"),
    lineLimits = TextFieldLineLimits.MultiLine(maxHeightInLines = 2),
    placeholder = { Text("") },
    textStyle = TextStyle(color = Color.Blue, fontWeight = FontWeight.Bold),
    label = { Text("Enter text") },
    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 Material TextField atau OutlinedTextField. Namun, BasicTextField harus digunakan saat mem-build desain yang tidak memerlukan dekorasi dari spesifikasi Material.

Gaya input dengan Brush API

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

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

Mengimplementasikan gradien berwarna menggunakan TextStyle

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

val brush = remember {
    Brush.linearGradient(
        colors = listOf(Color.Red, Color.Yellow, Color.Green, Color.Blue, Color.Magenta)
    )
}
TextField(
    state = rememberTextFieldState(), textStyle = TextStyle(brush = brush)
)

Menggunakan buildAnnotatedString dan SpanStyle, bersama dengan linearGradient, untuk menyesuaikan hanya sebagian teks.
Gambar 1. Efek gradien pelangi untuk konten TextField.

Mengelola status kolom teks

TextField menggunakan class holder status khusus yang disebut TextFieldState untuk konten dan pilihan saat ini. TextFieldState dirancang untuk diangkat di mana pun sesuai dengan arsitektur Anda. Ada 2 properti utama yang disediakan oleh TextFieldState:

  • initialText: Konten TextField.
  • initialSelection: Menunjukkan posisi kursor atau pilihan saat ini.

Yang membedakan TextFieldState dari pendekatan lain, seperti callback onValueChange, adalah TextFieldState sepenuhnya mengenkapsulasi seluruh alur input. Hal ini mencakup penggunaan struktur data pendukung yang benar, filter dan formator inline, serta menyinkronkan semua pengeditan yang berasal dari berbagai sumber.

Anda dapat menggunakan TextFieldState() untuk mengangkat status di TextField. Untuk itu, sebaiknya gunakan fungsi rememberTextFieldState(). rememberTextFieldState() membuat instance TextFieldState dalam composable Anda, memastikan objek status diingat, dan menyediakan fungsi simpan dan pemulihan bawaan:

val usernameState = rememberTextFieldState()
TextField(
    state = usernameState,
    lineLimits = TextFieldLineLimits.SingleLine,
    placeholder = { Text("Enter Username") }
)

rememberTextFieldState dapat memiliki parameter kosong atau memiliki nilai awal yang diteruskan untuk merepresentasikan nilai teks saat inisialisasi. Jika nilai yang berbeda diteruskan dalam rekomposisi berikutnya, nilai status tidak akan diperbarui. Untuk memperbarui status setelah diinisialisasi, panggil metode edit di TextFieldState.

TextField(
    state = rememberTextFieldState(initialText = "Username"),
    lineLimits = TextFieldLineLimits.SingleLine,
)

TextField dengan teks Username yang muncul di dalam kolom teks.
Gambar 2. TextField dengan "Nama Pengguna" sebagai teks awal.

Mengubah teks dengan TextFieldBuffer

TextFieldBuffer berfungsi sebagai penampung teks yang dapat diedit, yang fungsinya mirip dengan StringBuilder. Class ini menyimpan konten teks dan informasi tentang pilihan saat ini.

Anda sering menemukan TextFieldBuffer sebagai cakupan penerima pada fungsi seperti TextFieldState.edit, InputTransformation.transformInput, atau OutputTransformation.transformOutput. Dalam fungsi ini, Anda dapat membaca atau memperbarui TextFieldBuffer sesuai kebutuhan. Setelah itu, perubahan ini di-commit ke TextFieldState, atau diteruskan ke pipeline rendering dalam hal OutputTransformation.

Anda dapat menggunakan fungsi pengeditan standar seperti append, insert, replace, atau delete untuk mengubah konten buffering. Untuk mengubah status pemilihan, tetapkan variabel selection: TextRange secara langsung, atau gunakan fungsi utilitas seperti placeCursorAtEnd atau selectAll. Pilihan itu sendiri diwakili oleh TextRange, dengan indeks awal bersifat inklusif dan indeks akhir bersifat eksklusif. TextRange dengan nilai awal dan akhir yang identik, seperti (3, 3), menandakan posisi kursor tanpa karakter yang saat ini dipilih.

val phoneNumberState = rememberTextFieldState()

LaunchedEffect(phoneNumberState) {
    phoneNumberState.edit { // TextFieldBuffer scope
        append("123456789")
    }
}

TextField(
    state = phoneNumberState,
    inputTransformation = InputTransformation { // TextFieldBuffer scope
        if (asCharSequence().isDigitsOnly()) {
            revertAllChanges()
        }
    },
    outputTransformation = OutputTransformation {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
)

Mengedit teks di TextFieldState

Ada beberapa metode yang memungkinkan Anda mengedit status secara langsung melalui variabel status:

  • edit: Memungkinkan Anda mengedit konten status dan memberi Anda fungsi TextFieldBuffer sehingga Anda dapat menggunakan metode seperti insert, replace, append, dan lainnya.

    val usernameState = rememberTextFieldState("I love Android")
    // textFieldState.text : I love Android
    // textFieldState.selection: TextRange(14, 14)
    usernameState.edit { insert(14, "!") }
    // textFieldState.text : I love Android!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { replace(7, 14, "Compose") }
    // textFieldState.text : I love Compose!
    // textFieldState.selection: TextRange(15, 15)
    usernameState.edit { append("!!!") }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(18, 18)
    usernameState.edit { selectAll() }
    // textFieldState.text : I love Compose!!!!
    // textFieldState.selection: TextRange(0, 18)

  • setTextAndPlaceCursorAtEnd: Menghapus teks saat ini, menggantinya dengan teks yang diberikan, dan menyetel kursor di bagian akhir.

    usernameState.setTextAndPlaceCursorAtEnd("I really love Android")
    // textFieldState.text : I really love Android
    // textFieldState.selection : TextRange(21, 21)

  • clearText: Menghapus semua teks.

    usernameState.clearText()
    // textFieldState.text :
    // textFieldState.selection : TextRange(0, 0)

Untuk fungsi TextFieldState lainnya, lihat referensi TextFieldState.

Mengubah input pengguna

Bagian berikut menjelaskan cara mengubah input pengguna. Transformasi input memungkinkan Anda memfilter input TextField saat pengguna mengetik, sedangkan transformasi output memformat input pengguna sebelum ditampilkan di layar.

Memfilter input pengguna dengan transformasi input

Transformasi input memungkinkan Anda memfilter input dari pengguna. Misalnya, jika TextField Anda menerima nomor telepon Amerika, Anda hanya ingin menerima 10 digit. Hasil InputTransformation disimpan di TextFieldState.

Ada filter bawaan untuk kasus penggunaan InputTransformation yang umum. Untuk membatasi panjang, panggil InputTransformation.maxLength():

TextField(
    state = rememberTextFieldState(),
    lineLimits = TextFieldLineLimits.SingleLine,
    inputTransformation = InputTransformation.maxLength(10)
)

Transformasi input kustom

InputTransformation adalah antarmuka fungsi tunggal. Saat menerapkan InputTransformation kustom, Anda perlu mengganti TextFieldBuffer.transformInput:

class CustomInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
    }
}

Untuk nomor telepon, tambahkan transformasi input kustom yang hanya mengizinkan digit diketik ke dalam TextField:

class DigitOnlyInputTransformation : InputTransformation {
    override fun TextFieldBuffer.transformInput() {
        if (!TextUtils.isDigitsOnly(asCharSequence())) {
            revertAllChanges()
        }
    }
}

Menyambungkan transformasi input

Untuk menambahkan beberapa filter pada input teks, rantaikan InputTransformation menggunakan fungsi ekstensi then. Filter dieksekusi secara berurutan. Sebagai praktik terbaik, terapkan filter yang paling selektif terlebih dahulu untuk menghindari transformasi yang tidak perlu pada data yang pada akhirnya akan difilter.

TextField(
    state = rememberTextFieldState(),
    inputTransformation = InputTransformation.maxLength(6)
        .then(CustomInputTransformation()),
)

Setelah menambahkan transformasi input, input TextField menerima maksimum 10 digit.

Memformat input sebelum ditampilkan

OutputTransformation memungkinkan Anda memformat input pengguna sebelum dirender di layar. Tidak seperti InputTransformation, pemformatan yang dilakukan melalui OutputTransformation tidak disimpan di TextFieldState. Berdasarkan contoh nomor telepon sebelumnya, Anda perlu menambahkan tanda kurung dan tanda hubung di tempat yang sesuai:

Nomor telepon Amerika, yang diformat dengan benar menggunakan tanda kurung, tanda hubung, dan indeks yang sesuai.
Gambar 3. Nomor telepon Amerika dengan format yang benar dan indeks yang sesuai.

Ini adalah cara terbaru untuk menangani VisualTransformation dalam TextField berbasis nilai, dengan perbedaan utamanya adalah Anda tidak perlu menghitung pemetaan offset-nya.

OutputTransformation adalah antarmuka metode abstrak tunggal. Untuk mengimplementasikan OutputTransformation kustom, Anda harus mengganti metode transformOutput:

class CustomOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
    }
}

Untuk memformat nomor telepon, tambahkan tanda kurung buka di indeks 0, tanda kurung tutup di indeks 4, dan tanda hubung di indeks 8 ke OutputTransformation Anda:

class PhoneNumberOutputTransformation : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        if (length > 0) insert(0, "(")
        if (length > 4) insert(4, ")")
        if (length > 8) insert(8, "-")
    }
}

Selanjutnya, tambahkan OutputTransformation ke TextField:

TextField(
    state = rememberTextFieldState(),
    outputTransformation = PhoneNumberOutputTransformation()
)

Cara transformasi bekerja sama

Diagram berikut menunjukkan alur dari input teks ke transformasi ke output:

Visualisasi tentang bagaimana input teks melalui transformasi sebelum menjadi output teks.
Gambar 4. Diagram yang menunjukkan bagaimana input teks mengalami transformasi sebelum menjadi output teks.
  1. Input diterima dari sumber input.
  2. Input difilter melalui InputTransformation, yang disimpan di TextFieldState.
  3. Input diteruskan melalui OutputTransformation untuk pemformatan.
  4. Input ditampilkan di TextField.

Menetapkan 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

Referensi lainnya