Rendi EditText di sola lettura


119

Voglio creare una visualizzazione di sola lettura EditText. L'XML per fare questo codice sembra essere android:editable="false", ma voglio farlo nel codice.

Come posso fare questo?



3
Vale anche la pena notare che android:editableè deprecato per EditText.
Derek W

Il modo più affidabile per farlo è usare UI.setReadOnly(myEditText, true)da questa libreria . Ci sono alcune proprietà che devono essere impostate, che puoi controllare nel codice sorgente .
caw

3
Sì, Derek ha ragione. Ora in XML dovresti usare android:inputType="none"eandroid:textIsSelectable="true"
Atul

Risposte:


135

Si prega di utilizzare questo codice ..

Edittext.setEnabled(false);

34
questo non solo 'imposterà' la sola lettura ma disabiliterà anche lo scorrimento e la copia :-(
josef

1
Questo disabilita. Inutile soprattutto per EditText multilinea.
Atul

provare questo ma ha perso valore?
fdurmus77

97

Se setEnabled(false)poi editTextappariresti disabilitato (grigio, ecc.). Potresti non voler cambiare l'aspetto visivo del tuo editor.

Un modo meno invadente sarebbe quello di usare setFocusable(false).

Credo che questo risponda alla tua domanda più vicino al tuo intento iniziale.


8
Questo va bene, ma l'utente può ancora "Incollare" nel campo di testo.
xtrem

14
Questo ha funzionato benissimo per me. Avevo bisogno che fosse cliccabile, quindi non potevo usare setEnabled (false). Per aggirare il problema incollabile, ho appena eseguito android: longClickable = "false"
dt0

3
Se usi setFocusable(false)(e anche setFocusableInTouchMode(false)con setClickable(false)) puoi ancora cambiare il valore della tua editTextpressione editTextper alcune centinaia di millisecondi e selezionare l' Pasteopzione a meno che gli appunti di sistema non siano vuoti. L'ho testato con la più recente API disponibile che è 23 .
patryk.beza

Funziona, sono in grado di scorrere e non vedere il cursore.
live-love

28

In XMLuso:

android:editable="false"

Come esempio:

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

Secondo Javadoc , l' editableattributo non sembra essere deprecato (almeno, non a partire dal livello API 23).
Greg Brown

8
@MichelJung ha ragione. devi usareandroid:inputType="none"
Ata Iravani

1
La domanda cerca un modo per rendere modificabile falso tramite codice Java non XML!
saeed khalafinejad

7
Sto provando android:inputType="none"e i dati sono ancora modificabili.
BlueMonkMN

24

Questo funziona per me:

EditText.setKeyListener(null);

5
Sarebbe stato bello, ma l'utente può ancora "incollare" nel campo. Complimenti comunque, anche se questo sembra un trucco. Vorrei che avessero un'API setEditable ().
xtrem

15

La cosa migliore è usare TextViewinvece.


8
secondo il flusso della sua app potrebbe essere necessario renderlo modificabile alcune volte e in altre no
Muhammed Refaat

15
editText.setInputType(InputType.TYPE_NULL);

Come da documentazione, ciò impedisce la visualizzazione della tastiera virtuale. Inoltre impedisce l'incollaggio, consente lo scorrimento e non altera l'aspetto visivo della visualizzazione. Tuttavia, ciò impedisce anche la selezione e la copia del testo all'interno della vista.

Dalle mie prove di impostazione setInputTypeper TYPE_NULLsembra essere funzionalmente equivalente al ammortizzati android:editable="false". Inoltre, android:inputType="none"sembra non avere alcun effetto evidente.


D'accordo, per ora funziona, e come hai detto android:inputType="none"non funziona più.
Goke Obasa

1
Sfortunatamente questo non impedisce di digitare nel campo se la tastiera virtuale è già aperta (cioè l'utente tocca prima un campo modificabile, poi su questo - la tastiera virtuale non si chiude). Inoltre non impedisce la digitazione nel campo da una tastiera esterna.
jk7

11

android: editable = "false" è stato deprecato. Pertanto non puoi usarlo per rendere il testo di modifica di sola lettura.

L'ho fatto usando la soluzione qui sotto. Qui ho usato

Android: InputType = "none"

Android: textIsSelectable = "true"

Android: = focusable "false"

Provaci :)

<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"/>

Non è realmente di sola lettura, puoi comunque incollare i valori in edittext in questo codice. android:enabled="false"può essere una buona alternativa.
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) : "";
    }
} });

Questo ti darà un filtro EditText non modificabile. devi prima mettere il testo che vuoi nel campo editText e poi applicare questo filtro.


2
Una buona soluzione e meno righe di codice di un TextWatcher. Ciò consente all'utente di selezionare e copiare il testo ma non modificare il testo digitando o TAGLIA o INCOLLA. La dichiarazione di return dst.subSequence(dstart, dend);
reso

Il mio commento precedente si riferiva solo all'istruzione setFilters () senza disabilitare il campo EditText.
jk7

Grazie, questa è l'unica soluzione che funziona per me! È frustrante che qualcosa funzionante sia stato deprezzato e sostituito con qualcosa (inputType = "none") che ancora non funziona e con effetti collaterali indesiderati (input multilinea). Si noti che la modifica suggerita da @ jk7 è vitale, perché con l'istruzione return originale, se si seleziona parte del testo originale e si digita qualcosa, si finirà per sostituire il testo selezionato con la stringa vuota restituita dal filtro. In questo caso la lunghezza di src è diversa da zero e la stringa vuota ha effetto.
Paul L

6

scrivere queste due righe è più che sufficiente per il tuo lavoro.

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

Molto più utile impostare il listener su null che disabilitarlo.
Humberto Castañeda


3

Prova a usare

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

Ciò consente comunque di essere attivabile premendo il tasto Tab dalla tastiera
AlanKley

3
android:editable

Se impostato, specifica che TextViewha un metodo di input. Sarà testuale a meno che non sia stato diversamente specificato. Perché TextViewquesto è falso per impostazione predefinita. Perché EditTextè vero per impostazione predefinita.

Deve essere un booleanvalore, trueo false.

Può anche essere un riferimento a una risorsa (nel modulo @[package:]type:name) o a un attributo del tema (nel modulo ?[package:][type:]name) contenente un valore di questo tipo.

Ciò corrisponde al simbolo della risorsa attributo globale modificabile.

Metodi correlati


2

Prova a sovrascrivere il listener onLongClick del testo di modifica per rimuovere il menu contestuale:

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

3
Ho usato android: editable = "false" e android: focusable = "false", quindi ho sovrascritto onLongclick e ho ottenuto il risultato che volevo
JannGabriel

2

Usa questo codice:

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

La disabilitazione editTextconferisce un aspetto e un comportamento di sola lettura , ma cambia anche text-colorin grigio, quindi è necessario impostare il colore del testo.


Aggiungi anche alcune spiegazioni.
Blackeard

1

questa è la mia implementazione (un po 'lunga, ma utile per me!): Con questo codice puoi rendere EditView di sola lettura o normale. anche in stato di sola lettura, il testo può essere copiato dall'utente. è possibile modificare lo sfondo per farlo sembrare diverso da un normale EditText.

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;
    }
}

il vantaggio di questo codice è che l'EditText viene visualizzato come normale EditText ma il contenuto non è modificabile. Il valore restituito deve essere mantenuto come una variabile per poter tornare dallo stato di sola lettura allo stato normale.

per rendere un EditText di sola lettura, basta metterlo come:

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

e per renderlo normale usa tw dall'istruzione precedente:

setReadOnly(editText, false, tw);

1

Questo ha funzionato per me, tenendo conto di molti dei suggerimenti sopra. Rende il TextEdit attivabile, ma se l'utente fa clic o si concentra, viene visualizzato un elenco di selezioni in una PopupWindow. (Stiamo sostituendo lo stravagante widget Spinner). TextEdit xml è molto generico ...

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

Se vuoi solo essere in grado di copiare il testo dal controllo ma non essere in grado di modificarlo, potresti voler usare invece un TextView e impostare il testo è selezionabile .

codice:

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"-->


La documentazione di setTextIsSelectable dice:

Quando chiami questo metodo per impostare il valore di textIsSelectable, imposta i flag focusable, focusableInTouchMode, clickable e longClickable sullo stesso valore ...

Tuttavia, ho dovuto impostare esplicitamente focusable e focusableInTouchMode su true per farlo funzionare con l'input tattile.


1

Questa era l'unica soluzione semplice e completa per me.

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

0

Non ho avuto problemi a rendere EditTextPreference di sola lettura, utilizzando:

editTextPref.setSelectable(false);

Funziona bene se abbinato all'uso del campo "riepilogo" per visualizzare campi di sola lettura (utile per visualizzare le informazioni sull'account, ad esempio). Aggiornamento dei campi di riepilogo strappati dinamicamente da 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

Impostalo nel file xml di EdiTextView

android:focusable="false"

1
La domanda chiede come renderlo di sola lettura a livello di codice, non in XML.
jk7

0

Poiché android:editable=""è deprecato,

Setting

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

lo renderà "di sola lettura".

Tuttavia, gli utenti potranno comunque incollare nel campo o eseguire qualsiasi altra azione di clic lungo. Per disabilitarlo, sovrascrivi semplicemente onLongClickListener ().
A Kotlin:

  • myEditText.setOnLongClickListener { true }

basta.


0

Il mio approccio a questo è stato la creazione di una classe TextWatcher personalizzata come segue:

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;
        }
    }
}

Quindi aggiungi quell'osservatore a qualsiasi campo che desideri venga letto solo nonostante sia abilitato:

editText.addTextChangedListener(new ReadOnlyTextWatcher(editText));
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.