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?

warna
sumber
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);
Nikhil
sumber
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.

Flexo
sumber
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" />
MaxEcho
sumber
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);
igorinov
sumber
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.

Egor
sumber
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.

Adrian Toman
sumber
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"/>
Chanaka Fernando
sumber
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.

DArkO
sumber
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);
Vishal Pandey
sumber
Jauh lebih bermanfaat jika menyetel pendengar menjadi nol daripada menonaktifkannya.
Humberto Castañeda
5

diatur dalam XML

android:inputType="none" 
Survei Jitendra
sumber
Saya sudah mencoba ini, dan hasilnya tampaknya masih bisa diedit.
BlueMonkMN
3

Coba gunakan

editText.setEnabled(false);
editText.setClickable(false);
kannappan.dll
sumber
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

jclafuente.dll
sumber
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;
    }
});
Jimmy Ilenloa
sumber
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.

Mary Garcia
sumber
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);
Ali sh
sumber
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);
    }
}  
Johnny O
sumber
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.

AJBauer
sumber
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
AlanKley
sumber
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());
        }
    }
}
Jason Harmon
sumber
0

Setel ini dalam file xml EdiTextView

android:focusable="false"
Nandakishore Shetty
sumber
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.

Chad Mx
sumber
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));
Fran Marzoa
sumber