Jadikan EditText ReadOnly


119

Saya ingin membuat tampilan hanya-baca EditText. XML untuk melakukan kode ini sepertinya android:editable="false", tetapi saya ingin melakukan ini dalam kode.

Bagaimana saya bisa melakukan ini?



3
Perlu juga dicatat bahwa android:editablesudah usang EditText.
Derek W

Cara paling andal untuk melakukannya adalah dengan menggunakan UI.setReadOnly(myEditText, true)dari pustaka ini . Ada beberapa properti yang harus disetel, yang dapat Anda periksa di kode sumber .
gak

3
Ya Derek benar. Sekarang dalam XML Anda harus menggunakan android:inputType="none"danandroid:textIsSelectable="true"
Atul

Jawaban:


135

Silakan gunakan kode ini ..

Edittext.setEnabled(false);

34
ini tidak hanya akan 'mengatur' hanya-baca tetapi juga menonaktifkan pengguliran dan penyalinan :-(
josef

1
Ini menonaktifkan. Tidak berguna terutama untuk EditText multiline.
Atul

coba ini tetapi kehilangan nilai?
fdurmus77

97

Jika Anda setEnabled(false)maka Anda editTextakan terlihat cacat (abu-abu, dll). Anda mungkin tidak ingin mengubah aspek visual editor Anda.

Cara yang tidak terlalu mengganggu adalah dengan menggunakan setFocusable(false).

Saya percaya bahwa ini menjawab pertanyaan Anda lebih dekat dengan maksud awal Anda.


8
Ini bagus, tetapi pengguna masih bisa "Tempel" di bidang teks.
xtrem

14
Ini bekerja dengan baik untuk saya. Saya membutuhkannya agar dapat diklik sehingga saya tidak dapat menggunakan setEnabled (false). Untuk mengatasi masalah dapat menempel, saya baru saja melakukan android: longClickable = "false"
dt0

3
Jika Anda menggunakan setFocusable(false)(dan bahkan setFocusableInTouchMode(false)dengan setClickable(false)) Anda masih dapat mengubah nilai Anda editTextmenekan Anda editTextselama beberapa ratus milidetik dan memilih Pasteopsi kecuali clipboard sistem kosong. Saya mengujinya dengan API terbaru yang tersedia yaitu 23 .
patryk.beza

Ini berfungsi, saya dapat menggulir dan tidak melihat kursor.
cinta hidup

28

Sedang XMLdigunakan:

android:editable="false"

Sebagai contoh:

<EditText
    android:id="@+id/EditText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:editable="false" />

Menurut Javadoc , editableatribut tersebut tampaknya tidak digunakan lagi (setidaknya, tidak pada API level 23).
Greg Brown

8
@MichelJung benar. Anda harus menggunakanandroid:inputType="none"
Ata Iravani

1
Pertanyaan tersebut mencari cara untuk membuat salah yang dapat diedit melalui kode Java, bukan XML!
saeed khalafinejad

7
Saya mencoba android:inputType="none"dan datanya masih dapat diedit.
BlueMonkMN

24

Ini bekerja untuk saya:

EditText.setKeyListener(null);

5
Ini akan bagus, tetapi pengguna masih bisa "menempel" di lapangan. Jempol, meskipun ini terlihat seperti retasan. Saya berharap mereka memiliki API setEditable ().
xtrem

15

Yang terbaik adalah dengan menggunakan TextView.


8
menurut aliran aplikasinya mungkin dia perlu membuatnya dapat diedit beberapa kali dan di lain waktu tidak
Muhammed Refaat

15
editText.setInputType(InputType.TYPE_NULL);

Sesuai dokumen, ini mencegah soft keyboard ditampilkan. Ini juga mencegah menempel, memungkinkan pengguliran, dan tidak mengubah aspek visual tampilan. Namun, ini juga mencegah pemilihan dan penyalinan teks dalam tampilan.

Dari pengaturan pengujian saya setInputTypehingga TYPE_NULLtampaknya secara fungsional setara dengan yang disusutkan android:editable="false". Selain itu, android:inputType="none"tampaknya tidak memiliki efek yang terlihat.


Setuju, ini berfungsi untuk saat ini, dan seperti yang Anda katakan android:inputType="none"tidak berfungsi lagi.
Goke Obasa

1
Sayangnya hal ini tidak mencegah pengetikan ke dalam bidang jika keyboard virtual sudah terbuka (yaitu pengguna mengetuk bidang yang dapat diedit terlebih dahulu, kemudian yang satu ini - keyboard virtual tidak menutup). Juga tidak mencegah pengetikan ke dalam bidang dari keyboard eksternal.
jk7

11

android: editable = "false" sudah tidak digunakan lagi. Oleh karena itu, Anda tidak dapat menggunakannya untuk membuat teks edit hanya-baca.

Saya telah melakukan ini menggunakan solusi di bawah ini. Di sini saya telah menggunakan

android: inputType = "none"

android: textIsSelectable = "true"

android: focusable = "false"

Cobalah :)

<EditText
         android:id="@+id/et_newsgpa_university"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
         android:hint="@string/hint_educational_institute"
         android:textSize="@dimen/regular_text"
         android:inputType="none"
         android:textIsSelectable="true"
         android:focusable="false"
         android:maxLines="1"
         android:imeOptions="actionNext"/>

Ini tidak benar-benar hanya untuk dibaca, Anda masih dapat menempelkan nilai ke teks edit dalam kode ini. android:enabled="false"mungkin alternatif yang bagus.
eVader

7
editText.setEnabled(false);
editText.setFilters(new InputFilter[] { new InputFilter() {
    public CharSequence filter(CharSequence src, int start, int end,
            Spanned dst, int dstart, int dend) {
        return src.length() < 1 ? dst.subSequence(dstart, dend) : "";
    }
} });

Ini akan memberi Anda filter EditText yang tidak dapat diedit. Anda harus terlebih dahulu meletakkan teks yang Anda inginkan di bidang editText dan kemudian menerapkan filter ini.


2
Solusi yang bagus, dan lebih sedikit baris kode daripada TextWatcher. Ini memungkinkan pengguna untuk memilih & menyalin teks tetapi tidak mengubah teks dengan mengetik atau CUT atau PASTE. Pernyataan kembali dapat disederhanakan menjadireturn dst.subSequence(dstart, dend);
jk7

Komentar saya sebelumnya hanya merujuk pada pernyataan setFilters () tanpa menonaktifkan bidang EditText.
jk7

Terima kasih, ini satu-satunya solusi yang berhasil untuk saya! Mengesalkan karena sesuatu yang berfungsi disusutkan, dan diganti dengan sesuatu (inputType = "none") yang masih tidak berfungsi, dan dengan efek samping yang tidak diinginkan (input multi-baris). Harap dicatat bahwa perubahan yang disarankan oleh @ jk7 sangat penting, karena dengan pernyataan pengembalian asli, jika Anda memilih bagian dari teks asli Anda, dan mengetik sesuatu, Anda akan mengganti teks yang dipilih dengan string kosong yang dikembalikan oleh filter. Dalam kasus ini, panjang src bukan nol, dan string kosong berpengaruh.
Paul L

6

menulis dua baris ini lebih dari cukup untuk pekerjaan Anda.

yourEditText.setKeyListener(null); 
yourEditText.setEnabled(false);

Jauh lebih bermanfaat jika menyetel pendengar menjadi nol daripada menonaktifkannya.
Humberto Castañeda


3

Coba gunakan

editText.setEnabled(false);
editText.setClickable(false);

Ini masih memungkinkannya menjadi fokus dengan menekan tab dari keyboard
AlanKley

3
android:editable

Jika disetel, tentukan bahwa ini TextViewmemiliki metode masukan. Ini akan menjadi teks kecuali telah ditentukan lain. Karena TextView, ini salah secara default. Sebab EditText, memang benar secara default.

Harus berupa booleannilai, trueatau false.

Ini juga bisa menjadi referensi ke sumber daya (dalam bentuk @[package:]type:name) atau atribut tema (dalam formulir ?[package:][type:]name) yang berisi nilai jenis ini.

Ini sesuai dengan simbol sumber daya atribut global yang dapat diedit.

Metode Terkait


2

Coba ganti listener onLongClick dari teks edit untuk menghapus menu konteks:

EditText myTextField = (EditText)findViewById(R.id.my_edit_text_id);
myTextField.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});

3
Saya telah menggunakan android: editable = "false" dan android: focusable = "false", lalu mengganti onLongclick dan mendapatkan hasil yang saya inginkan
JannGabriel

2

Gunakan kode ini:

editText.setEnabled(false);
editText.setTextColor(ContextCompat.getColor(context, R.color.black);

Penonaktifan editTextmemberikan tampilan dan perilaku hanya-baca tetapi juga mengubah text-colormenjadi abu-abu sehingga diperlukan pengaturan warna teksnya.


Harap tambahkan beberapa penjelasan juga.
BlackBeard

1

ini adalah implementasi saya (agak panjang, tapi berguna bagi saya!): Dengan kode ini Anda dapat membuat EditView Read-only atau Normal. bahkan dalam keadaan read-only, teks dapat disalin oleh pengguna. Anda dapat mengubah latar belakang agar terlihat berbeda dari EditText biasa.

public static TextWatcher setReadOnly(final EditText edt, final boolean readOnlyState, TextWatcher remove) {
    edt.setCursorVisible(!readOnlyState);
    TextWatcher tw = null;
    final String text = edt.getText().toString();
    if (readOnlyState) {
            tw = new TextWatcher();

            @Override
            public void afterTextChanged(Editable s) {

            }
            @Override
            //saving the text before change
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            // and replace it with content if it is about to change
            public void onTextChanged(CharSequence s, int start,int before, int count) {
                edt.removeTextChangedListener(this);
                edt.setText(text);
                edt.addTextChangedListener(this);
            }
        };
        edt.addTextChangedListener(tw);
        return tw;
    } else {
        edt.removeTextChangedListener(remove);
        return remove;
    }
}

manfaat dari kode ini adalah, EditText ditampilkan sebagai EditText normal tetapi isinya tidak dapat diubah. Nilai yang dikembalikan harus disimpan sebagai variabel agar seseorang dapat kembali dari status hanya-baca ke normal.

untuk membuat EditText hanya-baca, cukup taruh sebagai:

TextWatcher tw = setReadOnly(editText, true, null);

dan untuk membuatnya normal gunakan tw dari pernyataan sebelumnya:

setReadOnly(editText, false, tw);

1

Ini berhasil untuk saya, dengan mempertimbangkan beberapa saran di atas. Membuat TextEdit dapat difokuskan, tetapi jika pengguna mengklik atau memfokuskan, kami menampilkan daftar pilihan di PopupWindow. (Kami mengganti widget Spinner yang aneh). TextEdit xml sangat umum ...

public void onCreate(Bundle savedInstanceState) {
    ....  
    fEditState = (EditText) findViewById(R.id.state_edit);

    fEditState.setLongClickable(false);
    fEditState.setKeyListener(null);
    fEditState.setFocusable(true);

    fEditState.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        public void onFocusChange(View v, boolean hasFocus)
        {
            if (hasFocus)
            {
               showStatesPopup();

            }
        }
    });

    fEditState.setOnClickListener(new Button.OnClickListener(){

        public void onClick(View arg0)
        {
           showStatesPopup();
        }
    });
    ....
}

private void showStatesPopup()
{
    // fPopupWindowStates instantiated in OnCreate()

    if (!fPopupWindowStates.isShowing()) {
        // show the list view as dropdown
        fPopupWindowStates.showAsDropDown(fEditState, -5, 0);
    }
}  

1

Jika Anda hanya ingin dapat menyalin teks dari kontrol tetapi tidak dapat mengedit itu Anda mungkin ingin menggunakan TextView bukan dan set teks adalah dipilih .

kode:

myTextView.setTextIsSelectable(true);
myTextView.setFocusable(true);
myTextView.setFocusableInTouchMode(true);
// myTextView.setSelectAllOnFocus(true);

xml:

<TextView
    android:textIsSelectable="true"
    android:focusable="true"
    android:focusableInTouchMode="true"     
    ...
/>
<!--android:selectAllOnFocus="true"-->


Dokumentasi setTextIsSelectable mengatakan:

Saat Anda memanggil metode ini untuk menyetel nilai textIsSelectable, ini menyetel bendera focusable, focusableInTouchMode, clickable, dan longClickable ke nilai yang sama ...

Namun saya harus secara eksplisit mengatur focusable dan focusableInTouchMode ke true untuk membuatnya bekerja dengan input sentuh.


1

Ini adalah satu-satunya solusi sederhana penuh bagi saya.

editText.setEnabled(false);   // Prevents data entry
editText.setFocusable(false); // Prevents being able to tab to it from keyboard

0

Saya tidak mengalami masalah dalam membuat EditTextPreference hanya-baca, dengan menggunakan:

editTextPref.setSelectable(false);

Ini berfungsi dengan baik bila digabungkan dengan menggunakan bidang 'ringkasan' untuk menampilkan bidang hanya-baca (berguna untuk menampilkan info akun, misalnya). Memperbarui bidang ringkasan yang diambil secara dinamis dari http://gmariotti.blogspot.com/2013/01/preferenceactivity-preferencefragment.html

private static final List<String> keyList;

static {
    keyList = new ArrayList<String>();
    keyList.add("field1");
    keyList.add("field2");
    keyList.add("field3");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.preferences);

    for(int i=0;i<getPreferenceScreen().getPreferenceCount();i++){
        initSummary(getPreferenceScreen().getPreference(i));
    }
}

private void initSummary(Preference p) {
    if (p instanceof PreferenceCategory) {
        PreferenceCategory pCat = (PreferenceCategory) p;
        for (int i = 0; i < pCat.getPreferenceCount(); i++) {
            initSummary(pCat.getPreference(i));
        }
    } else {
        updatePrefSummary(p);
    }
}

private void updatePrefSummary(Preference p) {
    if (p instanceof ListPreference) {
        ListPreference listPref = (ListPreference) p;
        p.setSummary(listPref.getEntry());
    }
    if (p instanceof EditTextPreference) {
        EditTextPreference editTextPref = (EditTextPreference) p;
        //editTextPref.setEnabled(false); // this can be used to 'gray out' as well
        editTextPref.setSelectable(false);
        if (keyList.contains(p.getKey())) {
            p.setSummary(editTextPref.getText());
        }
    }
}

0

Setel ini dalam file xml EdiTextView

android:focusable="false"

1
Pertanyaannya menanyakan bagaimana membuatnya hanya-baca secara terprogram, bukan dalam XML.
jk7

0

Seperti yang android:editable=""sudah tidak berlaku lagi,

Setting

  • android:clickable="false"
  • android:focusable="false"
  • android:inputType="none"
  • android:cursorVisible="false"

akan membuatnya menjadi "hanya-baca".

Namun, pengguna masih dapat menempel ke bidang atau melakukan tindakan klik panjang lainnya. Untuk menonaktifkan ini, cukup ganti onLongClickListener ().
Di Kotlin:

  • myEditText.setOnLongClickListener { true }

sudah cukup.


0

Pendekatan saya untuk ini telah membuat kelas TextWatcher kustom sebagai berikut:

class ReadOnlyTextWatcher implements TextWatcher {
    private final EditText textEdit;
    private String originalText;
    private boolean mustUndo = true;

    public ReadOnlyTextWatcher(EditText textEdit) {
        this.textEdit = textEdit;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        if (mustUndo) {
            originalText = charSequence.toString();
        }
    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void afterTextChanged(Editable editable) {
        if (mustUndo) {
            mustUndo = false;
            textEdit.setText(originalText);
        } else {
            mustUndo = true;
        }
    }
}

Kemudian Anda cukup menambahkan pengamat itu ke bidang mana pun yang ingin Anda baca hanya meskipun diaktifkan:

editText.addTextChangedListener(new ReadOnlyTextWatcher(editText));
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.