Tornar EditText ReadOnly

119

Quero fazer uma EditTextexibição somente leitura . O XML para fazer esse código parece ser android:editable="false", mas eu quero fazer isso no código.

Como posso fazer isso?

Warna
fonte
3
Também é importante notar que isso android:editablefoi preterido EditText.
Derek W
A maneira mais confiável de fazer isso é usando a UI.setReadOnly(myEditText, true)partir desta biblioteca . Existem algumas propriedades que precisam ser definidas, que você pode conferir no código-fonte .
03
3
Sim, Derek está certo. Agora em XML você deve usar android:inputType="none"eandroid:textIsSelectable="true"
Atul

Respostas:

135

Por favor, use este código ..

Edittext.setEnabled(false);
Nikhil
fonte
34
isso não apenas 'definirá' somente leitura, mas também desabilitará a rolagem e a cópia :-(
josef
1
Isso desativa. Inútil, especialmente para o EditText de várias linhas.
Atul
tente isso, mas perdeu valor?
Fdurmus77
97

Se você setEnabled(false), em seguida, o seu editTextiria olhar desativada (cinza, etc). Você pode não querer alterar o aspecto visual do seu editor.

Uma maneira menos intrusiva seria usar setFocusable(false).

Acredito que isso responda à sua pergunta mais perto da sua intenção inicial.

Flexo
fonte
8
Isso é bom, mas o usuário ainda pode "Colar" no campo de texto.
Xtrem
14
Isso funcionou muito bem para mim. Eu precisava que fosse clicável para não poder usar setEnabled (false). Para contornar o problema de pasta-able, eu só fiz android: longClickable = "false"
DT0
3
Se você usar setFocusable(false)(e mesmo setFocusableInTouchMode(false)com setClickable(false)), ainda poderá alterar o valor editTextpressionando o botão editTextpor algumas centenas de milissegundos e selecionando a Pasteopção, a menos que a área de transferência do sistema esteja vazia. Eu testei com a mais recente API disponível, com 23 anos .
Patryk.beza 31/03
Isso funciona, eu sou capaz de rolar e não ver o cursor.
live-love
28

Em XMLuso:

android:editable="false"

Como um exemplo:

<EditText
    android:id="@+id/EditText1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:editable="false" />
MaxEcho
fonte
De acordo com o Javadoc , o editableatributo não parece estar obsoleto (pelo menos, não no nível 23 da API).
Greg Brown
8
@MichelJung está certo. você deve usarandroid:inputType="none"
Ata Iravani
1
A questão procura uma maneira de tornar editável falso através do código Java e não do XML!
Saeed khalafinejad
7
Estou tentando android:inputType="none"e os dados ainda são editáveis.
BlueMonkMN
24

Isso funciona para mim:

EditText.setKeyListener(null);
igorinov
fonte
5
Isso teria sido bom, mas o usuário ainda pode "colar" no campo. Polegares para cima de qualquer maneira, mesmo que isso pareça um hack. Eu gostaria que eles tivessem uma API setEditable ().
Xtrem
15

O melhor é usar em TextViewvez disso.

Egor
fonte
8
de acordo com o fluxo de aplicativos, ele pode ser necessário
editá
15
editText.setInputType(InputType.TYPE_NULL);

Conforme os documentos, isso impede que o teclado virtual seja exibido. Também evita a colagem, permite a rolagem e não altera o aspecto visual da visualização. No entanto, isso também impede a seleção e a cópia do texto na exibição.

Dos meus testes, setInputTypea configuração TYPE_NULLparece ser funcionalmente equivalente à depreciada android:editable="false". Além disso, android:inputType="none"parece não ter efeito perceptível.

Adrian Toman
fonte
Concordo, isso funciona por enquanto e, como você disse android:inputType="none", não funciona mais.
Goke Obasa
1
Infelizmente, isso não impede a digitação no campo se o teclado virtual já estiver aberto (ou seja, o usuário toca primeiro em um campo editável, depois neste - o teclado virtual não fecha). Além disso, não impede a digitação no campo a partir de um teclado externo.
Jk7:
11

android: editable = "false" foi preterido. Portanto, você não pode usá-lo para tornar o texto de edição somente leitura.

Eu fiz isso usando a solução abaixo. Aqui eu usei

android: inputType = "none"

android: textIsSelectable = "true"

android: focusable = "false"

Experimente :)

<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
fonte
Não é realmente somente leitura, você ainda pode colar valores no edittext neste código. android:enabled="false"pode ser uma boa alternativa.
sonegador
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) : "";
    }
} });

Isso fornecerá um filtro EditText não editável. primeiro você precisa colocar o texto que deseja no campo editText e aplicar esse filtro.

DArkO
fonte
2
Uma boa solução e menos linhas de código que um TextWatcher. Isso permite ao usuário selecionar e copiar texto, mas não alterar o texto digitando ou CUT ou PASTE. A declaração de retorno pode ser simplificada para apenasreturn dst.subSequence(dstart, dend);
jk7
Meu comentário anterior estava se referindo apenas à instrução setFilters () sem desativar o campo EditText.
Jk7 27/10
Obrigado, esta é a única solução que funciona para mim! É frustrante que algo funcione tenha sido depreciado e substituído por algo (inputType = "none") que ainda não está funcionando e por um efeito colateral indesejado (entrada de várias linhas). Observe que a alteração sugerida por @ jk7 é vital, pois com a declaração de retorno original, se você selecionar parte do texto original e digitar alguma coisa, acabará substituindo o texto selecionado pela string vazia retornada pelo filtro. Nesse caso, o comprimento do src é diferente de zero e a sequência vazia está tendo efeito.
Paul L
6

escrever essas duas linhas é mais que suficiente para o seu trabalho.

yourEditText.setKeyListener(null); 
yourEditText.setEnabled(false);
Vishal Pandey
fonte
Muito mais útil definir o ouvinte como nulo do que desativá-lo.
Humberto Castañeda
5

definido em XML

android:inputType="none" 
Jitendra Surve
fonte
Eu tentei isso, e o resultado ainda parece ser editável.
BlueMonkMN
3

Tente usar

editText.setEnabled(false);
editText.setClickable(false);
kannappan
fonte
Isso ainda permite que ele seja focusable por guia bater do teclado
AlanKley
3
android:editable

Se definido, especifica que este TextViewpossui um método de entrada. Será um texto, a menos que tenha sido especificado de outra forma. Pois TextView, isso é falso por padrão. Pois EditTexté verdade por padrão.

Deve ser um booleanvalor, trueou false.

Isso também pode ser uma referência a um recurso (no formulário @[package:]type:name) ou atributo de tema (no formulário ?[package:][type:]name) que contém um valor desse tipo.

Isso corresponde ao símbolo do recurso de atributo global editável.

Métodos relacionados

jclafuente
fonte
2

Tente substituir o ouvinte onLongClick do texto de edição para remover o menu de contexto:

EditText myTextField = (EditText)findViewById(R.id.my_edit_text_id);
myTextField.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});
Jimmy Ilenloa
fonte
3
Eu tenho usado android: editável = "false" e android: focalizável = "false", então overrided onLongclick e conseguimos o resultado que eu queria
JannGabriel
2

Use este código:

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

Desativar editTextfornece uma aparência e comportamento somente leitura, mas também muda text-colorpara cinza, portanto é necessário definir a cor do texto.

Mary Garcia
fonte
Por favor, adicione algumas explicações também.
Blackbeard
1

esta é a minha implementação (um pouco longa, mas útil para mim!): Com esse código, você pode tornar o EditView somente leitura ou Normal. mesmo no estado somente leitura, o texto pode ser copiado pelo usuário. você pode alterar o backgroud para torná-lo diferente de um 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;
    }
}

o benefício desse código é que, o EditText é exibido como o EditText normal, mas o conteúdo não é alterável. O valor de retorno deve ser mantido como uma variável para que se possa reverter do estado somente leitura para o normal.

para fazer um EditText somente leitura, basta colocá-lo como:

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

e para torná-lo normal, use tw da declaração anterior:

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

Isso funcionou para mim, levando em consideração várias das sugestões acima. Torna o TextEdit focalizável, mas se o usuário clicar ou focar, mostraremos uma lista de seleções em um PopupWindow. (Estamos substituindo o widget maluco do Spinner). TextEdit xml é muito 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
fonte
1

Se você deseja apenas copiar o texto do controle, mas não pode editá-lo, convém usar um TextView e definir o texto é selecionável .

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


A documentação de setTextIsSelectable diz:

Quando você chama esse método para definir o valor de textIsSelectable, ele define os sinalizadores como focusable, focusableInTouchMode, clickable e longClickable com o mesmo valor ...

No entanto, eu tive que definir explicitamente focusable e focusableInTouchMode como true para fazê-lo funcionar com a entrada por toque.

AJBauer
fonte
1

Esta foi a única solução simples e completa para mim.

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

Não tive problemas para tornar EditTextPreference somente leitura, usando:

editTextPref.setSelectable(false);

Isso funciona bem quando associado ao uso do campo 'resumo' para exibir campos somente leitura (útil para exibir informações da conta, por exemplo). Atualizando os campos de resumo capturados dinamicamente em 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
fonte
0

Defina isso no arquivo xml do EdiTextView

android:focusable="false"
Nandakishore Shetty
fonte
1
A pergunta pergunta como torná-lo somente leitura programaticamente, não em XML.
Jk7
0

Como android:editable=""está obsoleto,

Configuração

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

tornará "somente leitura".

No entanto, os usuários ainda poderão colar no campo ou executar outras ações de clique longo. Para desativar isso, basta substituir onLongClickListener ().
Em Kotlin:

  • myEditText.setOnLongClickListener { true }

é suficiente.

Chad Mx
fonte
0

Minha abordagem para isso foi criar uma classe TextWatcher personalizada da seguinte maneira:

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

Em seguida, basta adicionar esse observador a qualquer campo que você queira ler somente apesar de estar ativado:

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