Hacer que EditText sea de solo lectura

119

Quiero hacer una EditTextvista de solo lectura . El XML para hacer este código parece serlo android:editable="false", pero quiero hacerlo en código.

¿Cómo puedo hacer esto?

advertir
fuente
3
También vale la pena señalar que android:editableestá en desuso EditText.
Derek W
La forma más confiable de hacer esto es usar UI.setReadOnly(myEditText, true)de esta biblioteca . Hay algunas propiedades que deben configurarse, que puede consultar en el código fuente .
caw
3
Sí, Derek tiene razón. Ahora en XML debería usar android:inputType="none"yandroid:textIsSelectable="true"
Atul

Respuestas:

135

Utilice este código.

Edittext.setEnabled(false);
Nikhil
fuente
34
esto no solo 'establecerá' solo lectura, sino que también deshabilitará el desplazamiento y la copia :-(
josef
1
Esto desactiva. Inútil especialmente para EditText multilínea.
Atul
intente esto pero perdió valor?
fdurmus77
97

Si setEnabled(false)entonces editTextse verá deshabilitado (gris, etc.). Es posible que no desee cambiar el aspecto visual de su editor.

Una forma menos intrusiva sería usar setFocusable(false).

Creo que esto responde a su pregunta más cerca de su intención inicial.

Flexo
fuente
8
Esto es bueno, pero el usuario aún puede "Pegar" en el campo de texto.
xtrem
14
Esto funciono muy bien para mi. Necesitaba poder hacer clic en él para no poder usar setEnabled (false). Para solucionar el problema de pegar, acabo de hacer android: longClickable = "false"
dt0
3
Si usa setFocusable(false)(e incluso setFocusableInTouchMode(false)con setClickable(false)) aún puede cambiar el valor de su editTextpresionando su editTextdurante unos cientos de milisegundos y seleccionando la Pasteopción a menos que el portapapeles del sistema esté vacío. Lo probé con la API más nueva disponible, que es 23 .
patryk.beza
Esto funciona, puedo desplazarme y no ver el cursor.
amor vivo
28

En XMLuso:

android:editable="false"

Como ejemplo:

<EditText
    android:id="@+id/EditText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:editable="false" />
MaxEcho
fuente
Según el Javadoc , el editableatributo no parece estar obsoleto (al menos, no a partir del nivel de API 23).
Greg Brown
8
@MichelJung tiene razón. debe usarandroid:inputType="none"
Ata Iravani
1
¡La pregunta busca una manera de hacer editable false a través del código Java, no XML!
saeed khalafinejad
7
Lo estoy intentando android:inputType="none"y los datos aún se pueden editar.
BlueMonkMN
24

Esto funciona para mi:

EditText.setKeyListener(null);
igorinov
fuente
5
Esto habría sido bueno, pero el usuario aún puede "pegar" en el campo. Aprobado de todos modos, aunque esto parece un truco. Ojalá tuvieran una API setEditable ().
xtrem
15

Lo mejor es usar en su TextViewlugar.

Egor
fuente
8
de acuerdo con el flujo de su aplicación, puede ser que necesite hacerla editable algunas veces y en otras no
Muhammed Refaat
15
editText.setInputType(InputType.TYPE_NULL);

Según los documentos, esto evita que se muestre el teclado virtual. También evita el pegado, permite el desplazamiento y no altera el aspecto visual de la vista. Sin embargo, esto también evita la selección y copia del texto dentro de la vista.

De mis pruebas establecer setInputTypea TYPE_NULLque parece ser funcionalmente equivalente a la depreciado android:editable="false". Además, android:inputType="none"parece no tener ningún efecto notable.

Adrian Toman
fuente
De acuerdo, esto funciona por ahora, y como dijiste android:inputType="none"ya no funciona.
Goke Obasa
1
Desafortunadamente, esto no impide escribir en el campo si el teclado virtual ya está abierto (es decir, el usuario toca primero un campo editable y luego este; el teclado virtual no se cierra). Además, no impide escribir en el campo desde un teclado externo.
jk7
11

android: editable = "false" ha quedado obsoleto. Por lo tanto, no puede usarlo para hacer que el texto editado sea de solo lectura.

He hecho esto usando la siguiente solución. Aquí he usado

android: inputType = "ninguno"

android: textIsSelectable = "true"

android: focusable = "falso"

Pruébalo :)

<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"/>
Fernando Chanaka
fuente
Realmente no es de solo lectura, aún puede pegar valores para editar texto en este código. android:enabled="false"puede ser una buena 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) : "";
    }
} });

Esto le dará un filtro EditText no editable. primero debe poner el texto que desea en el campo editText y luego aplicar este filtro.

DArkO
fuente
2
Una buena solución y menos líneas de código que un TextWatcher. Esto permite al usuario seleccionar y copiar texto, pero no cambiar el texto escribiendo o CORTAR o PEGAR. La declaración de devolución se puede simplificar a soloreturn dst.subSequence(dstart, dend);
jk7
Mi comentario anterior se refería solo a la declaración setFilters () sin deshabilitar el campo EditText.
jk7
Gracias, esta es la única solución que me funciona. Es frustrante que algo que funcionaba se depreciara y se reemplazara con algo (inputType = "none") que todavía no funciona, y con efectos secundarios no deseados (entrada de varias líneas). Tenga en cuenta que el cambio sugerido por @ jk7 es vital, porque con la declaración de devolución original, si selecciona parte de su texto original y escribe algo, terminará reemplazando el texto seleccionado con la cadena vacía devuelta por el filtro. En este caso, la longitud de src no es cero y la cadena vacía está teniendo efecto.
Paul L
6

escribir estas dos líneas es más que suficiente para tu trabajo.

yourEditText.setKeyListener(null); 
yourEditText.setEnabled(false);
Vishal Pandey
fuente
Es mucho más útil establecer el oyente en nulo que deshabilitarlo.
Humberto Castañeda
5

establecido en XML

android:inputType="none" 
Jitendra Surve
fuente
Lo intenté y el resultado aún parece ser editable.
BlueMonkMN
3

Intenta usar

editText.setEnabled(false);
editText.setClickable(false);
kannappan
fuente
Esto aún permite que se pueda
enfocar presionando la
3
android:editable

Si se establece, especifica que TextViewtiene un método de entrada. Será textual a menos que se especifique lo contrario. Porque TextViewesto es falso por defecto. Porque EditTextes cierto por defecto.

Debe ser un booleanvalor, ya sea trueo false.

Esto también puede ser una referencia a un recurso (en el formulario @[package:]type:name) o atributo de tema (en el formulario ?[package:][type:]name) que contiene un valor de este tipo.

Esto corresponde al símbolo de recurso de atributo global editable.

Métodos relacionados

jclafuente
fuente
2

Intente anular el oyente onLongClick del texto de edición para eliminar el menú contextual:

EditText myTextField = (EditText)findViewById(R.id.my_edit_text_id);
myTextField.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});
Jimmy Ilenloa
fuente
3
He usado android: editable = "false" y android: focusable = "false", luego anulé onLongclick y obtuve el resultado que quería
JannGabriel
2

Utilice este código:

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

La desactivación editTextproporciona un aspecto y un comportamiento de solo lectura, pero también cambia text-colora gris, por lo que es necesario configurar el color del texto.

María García
fuente
Por favor, agregue también algunas explicaciones.
BlackBeard
1

esta es mi implementación (un poco larga, ¡pero útil para mí!): Con este código puede hacer que EditView sea de solo lectura o Normal. incluso en estado de solo lectura, el usuario puede copiar el texto. puede cambiar el fondo para que se vea diferente de un EditText normal.

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

el beneficio de este código es que EditText se muestra como EditText normal pero el contenido no se puede cambiar. El valor de retorno debe mantenerse como una variable para que uno pueda volver del estado de solo lectura a normal.

para hacer un EditText de solo lectura, simplemente póngalo como:

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

y para que sea normal, use tw de la declaración anterior:

setReadOnly(editText, false, tw);
Ali sh
fuente
1

Esto funcionó para mí, teniendo en cuenta varias de las sugerencias anteriores. Hace que TextEdit se pueda enfocar, pero si el usuario hace clic o enfoca, mostramos una lista de selecciones en una ventana emergente. (Estamos reemplazando el loco widget Spinner). TextEdit xml es muy genérico ...

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
fuente
1

Si solo desea poder copiar texto del control pero no puede editarlo, es posible que desee usar un TextView en su lugar y establecer que el texto sea seleccionable .

código:

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 documentación de setTextIsSelectable dice:

Cuando llama a este método para establecer el valor de textIsSelectable, establece los indicadores focusable, focusableInTouchMode, clickable y longClickable en el mismo valor ...

Sin embargo, tuve que establecer explícitamente focusable y focusableInTouchMode en true para que funcionara con la entrada táctil.

AJBauer
fuente
1

Esta fue la única solución completa y simple para mí.

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

No tuve ningún problema para hacer EditTextPreference de solo lectura, usando:

editTextPref.setSelectable(false);

Esto funciona bien cuando se combina con el uso del campo 'resumen' para mostrar campos de solo lectura (útil para mostrar información de cuenta, por ejemplo). Actualización de los campos de resumen extraídos dinámicamente de 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
fuente
0

Establezca esto en el archivo xml EdiTextView

android:focusable="false"
Nandakishore Shetty
fuente
1
La pregunta es cómo hacer que sea de solo lectura mediante programación, no en XML.
jk7
0

Como android:editable=""está en desuso,

Setting

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

lo hará "de sólo lectura".

Sin embargo, los usuarios aún podrán pegar en el campo o realizar cualquier otra acción de clic largo. Para deshabilitar esto, simplemente anule onLongClickListener ().
En Kotlin:

  • myEditText.setOnLongClickListener { true }

es suficiente.

Chad Mx
fuente
0

Mi enfoque para esto ha sido crear una clase TextWatcher personalizada de la siguiente manera:

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

Luego, simplemente agregue ese observador a cualquier campo que desee que sea de solo lectura a pesar de estar habilitado:

editText.addTextChangedListener(new ReadOnlyTextWatcher(editText));
Fran Marzoa
fuente