Saya memiliki EditText dengan beberapa teks yang sudah ada sebelumnya yang TIDAK HARUS dihapus. Pengguna seharusnya hanya diizinkan untuk menambahkan teks dalam tampilan.

Solusi yang saya miliki saat ini dapat dilihat di bawah, di mana saya memeriksa apakah panjang baru EditText lebih pendek dari teks aslinya. Jika ya, pengguna telah mencoba untuk menghapus karakter jadi saya hanya mengisi kembali tampilan dengan teks asli dan memindahkan kursor. Masalah dengan solusi ini adalah pengguna cukup memasukkan teks yang lebih panjang dari panjang aslinya, kemudian mengubah posisi kursor ke suatu tempat di dalam teks asli, dan akhirnya menghapus karakter.

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val originalText = "Hello"
    binding.et.setText(originalText)
    
    binding.et.addTextChangedListener(object : TextWatcher {
        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            s?.let {
                if (s.length < originalText.length) {
                    binding.et.setText(originalText)
                    binding.et.setSelection(originalText.count())
                }
            }
        }

        override fun afterTextChanged(s: Editable?) {}
    })
}

Apa yang harus saya lakukan? Saya terbuka untuk semua ide.

Terima kasih!

Sunting:

Saya juga mencoba menggabungkan EditText dan TextView (seperti yang disarankan beberapa orang) tetapi tata letaknya sulit dicapai karena teks asli dan teks baru dapat menjangkau beberapa baris. Solusi saya di atas mengandung satu kata dalam teks asli tetapi bisa jadi banyak. Jadi saya perlu memenuhi skenario ini:

textview and edittext

...di mana kotak putih mewakili TextView dan kotak merah mewakili EditText.

Saya rasa jawaban Bö macht Blau juga tidak akan berfungsi karena awalannya ada di "kolom" sendiri.

Saya pikir saya harus menggunakan solusi Zain dengan (startsWith()) atau membuat tampilan khusus (meskipun saya belum pernah melakukan salah satu dari ini sebelumnya).

1
BobSacamano 16 Januari 2021, 21:01

3 jawaban

Jawaban Terbaik

Harap pertimbangkan saran @Gabe Sechan dalam komentar OP bahwa EditText saja bukanlah solusi optimal untuk itu.

Jika Anda masih perlu menggunakan EditText, Anda dapat mengubah ketentuan untuk memeriksa bahwa CharSequence pengamat EditText yang dikembalikan dimulai dengan teks asli menggunakan startsWith() metode

et.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}

    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        s?.let {

            if (!s.startsWith(originalText)) {

                if (s.length <= originalText.length) {
                    et.setText(originalText)
                    et.setSelection(originalText.count())
                } else {
                    et.setText(originalText + s.subSequence(originalText.length, s.length))
                    et.setSelection(s.count())
                }
            }
        }
    }

    override fun afterTextChanged(s: Editable?) {}
})
1
Zain 16 Januari 2021, 18:37

Anda dapat menggunakan bidang teks, yang merupakan kombinasi dari TextInputEditText dan TextInputLayout. Kemudian Anda dapat mengatur awalan seperti:

<com.google.android.material.textfield.TextInputLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:prefixText="@string/prefix_text">

     <com.google.android.material.textfield.TextInputEditText
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>

 </com.google.android.material.textfield.TextInputLayout>

Awalan akan terlihat segera setelah TextInputEditText mendapatkan fokus. Karena itu bukan bagian dari konten EditText, itu tidak dapat diubah oleh pengguna.

Tautan yang berguna:

1
Bö macht Blau 16 Januari 2021, 20:26

Pemeriksaan ini harus berfungsi:

if (s.substring(0, 4) == originalText) {
  // update text
}

Tetapi pertimbangkan untuk melihat InputFilter, seperti yang disarankan oleh komentar.

0
Noah 16 Januari 2021, 18:13