Rendre EditText ReadOnly


119

Je souhaite créer une vue en lecture seule EditText. Le XML pour faire ce code semble être android:editable="false", mais je veux le faire dans le code.

Comment puis-je faire ceci?



3
Il convient également de noter qu'il android:editableest obsolète pour EditText.
Derek W

Le moyen le plus fiable de le faire est d'utiliser à UI.setReadOnly(myEditText, true)partir de cette bibliothèque . Il y a quelques propriétés qui doivent être définies, que vous pouvez vérifier dans le code source .
caw

3
Oui, Derek a raison. Maintenant, en XML, vous devriez utiliser android:inputType="none"etandroid:textIsSelectable="true"
Atul

Réponses:


135

Veuillez utiliser ce code.

Edittext.setEnabled(false);

34
cela non seulement `` définira '' la lecture seule, mais désactivera également le défilement et la copie :-(
josef

1
Cela désactive. Inutile surtout pour EditText multiligne.
Atul

essayez ceci mais perdez de la valeur?
fdurmus77

97

Si vous avez setEnabled(false)alors l' editTextair désactivé (gris, etc.). Vous ne souhaiterez peut-être pas modifier l'aspect visuel de votre éditeur.

Une manière moins intrusive serait d'utiliser setFocusable(false).

Je pense que cela répond à votre question plus proche de votre intention initiale.


8
C'est bien, mais l'utilisateur peut toujours "Coller" dans le champ de texte.
xtrem

14
Cela a très bien fonctionné pour moi. J'avais besoin qu'il soit cliquable, donc je ne pouvais pas utiliser setEnabled (false). Pour contourner le problème de collage, je viens de faire android: longClickable = "false"
dt0

3
Si vous utilisez setFocusable(false)(et même setFocusableInTouchMode(false)avec setClickable(false)), vous pouvez toujours modifier la valeur de votre editTextappui sur votre editTextpendant quelques centaines de millisecondes et en sélectionnant l' Pasteoption à moins que le presse - papiers système ne soit vide. Je l'ai testé avec la dernière API disponible qui est 23 .
patryk.beza

Cela fonctionne, je suis capable de faire défiler et de ne pas voir le curseur.
live-love

28

En cours d' XMLutilisation:

android:editable="false"

Par exemple:

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

Selon la Javadoc , l' editableattribut ne semble pas être obsolète (du moins, pas à partir du niveau 23 d'API).
Greg Brown

8
@MichelJung a raison. vous devez utiliserandroid:inputType="none"
Ata Iravani

1
La question cherche un moyen de rendre modifiable false via du code Java et non XML!
saeed khalafinejad

7
J'essaye android:inputType="none"et les données sont toujours modifiables.
BlueMonkMN

24

Cela fonctionne pour moi:

EditText.setKeyListener(null);

5
Cela aurait été bien, mais l'utilisateur peut toujours "coller" dans le champ. Bravo quand même, même si cela ressemble à un hack. J'aimerais qu'ils aient une API setEditable ().
xtrem

15

Le mieux est d'utiliser à la TextViewplace.


8
selon le flux de son application, il se peut qu'il ait besoin de le rendre modifiable à certains moments et à d'autres pas
Muhammed Refaat

15
editText.setInputType(InputType.TYPE_NULL);

Selon la documentation, cela empêche le clavier virtuel d'être affiché. Il empêche également le collage, permet le défilement et ne modifie pas l'aspect visuel de la vue. Cependant, cela empêche également la sélection et la copie du texte dans la vue.

De mes tests réglage setInputTypeà TYPE_NULLsemble être fonctionnellement équivalente à la dépréciée android:editable="false". De plus, android:inputType="none"semble n'avoir aucun effet notable.


D'accord, cela fonctionne pour le moment, et comme vous l'avez dit, android:inputType="none"cela ne fonctionne plus.
Goke Obasa

1
Malheureusement, cela n'empêche pas de taper dans le champ si le clavier virtuel est déjà ouvert (c'est-à-dire que l'utilisateur tape d'abord sur un champ modifiable, puis sur celui-ci - le clavier virtuel ne se ferme pas). De plus, cela n'empêche pas de taper dans le champ à partir d'un clavier externe.
jk7

11

android: editable = "false" est obsolète. Par conséquent, vous ne pouvez pas l'utiliser pour rendre le texte d'édition en lecture seule.

J'ai fait cela en utilisant la solution ci-dessous. Ici, j'ai utilisé

android: inputType = "aucun"

android: textIsSelectable = "true"

android: focusable = "faux"

Essayez-le :)

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

Ce n'est pas vraiment en lecture seule, vous pouvez toujours coller des valeurs dans edittext dans ce code. android:enabled="false"peut être une bonne alternative.
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) : "";
    }
} });

Cela vous donnera un filtre EditText non modifiable. vous devez d'abord mettre le texte souhaité dans le champ editText, puis appliquer ce filtre.


2
Une bonne solution, et moins de lignes de code qu'un TextWatcher. Cela permet à l'utilisateur de sélectionner et copier du texte mais pas de modifier le texte en tapant ou CUT ou COLLER. L'instruction de retour peut être simplifiée à justereturn dst.subSequence(dstart, dend);
jk7

Mon commentaire précédent faisait référence uniquement à l'instruction setFilters () sans désactiver le champ EditText.
jk7

Merci, c'est la seule solution qui fonctionne pour moi! Il est frustrant que quelque chose de fonctionnel ait été déprécié, et remplacé par quelque chose (inputType = "none") qui ne fonctionne toujours pas, et avec des effets secondaires indésirables (entrée multiligne). Veuillez noter que la modification suggérée par @ jk7 est vitale, car avec l'instruction de retour d'origine, si vous sélectionnez une partie de votre texte d'origine et saisissez quelque chose, vous finirez par remplacer le texte sélectionné par la chaîne vide renvoyée par le filtre. Dans ce cas, la longueur de src est différente de zéro et la chaîne vide a un effet.
Paul L

6

écrire ces deux lignes est plus que suffisant pour votre travail.

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

Il est bien plus utile de définir l'écouteur comme nul que de le désactiver.
Humberto Castañeda


3

Essayez d'utiliser

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

Cela lui permet toujours d'être focalisable en appuyant sur l'onglet du clavier
AlanKley

3
android:editable

S'il est défini, spécifie qu'il TextViewpossède une méthode d'entrée. Ce sera un texte, sauf indication contraire. Pour TextView, c'est faux par défaut. Car EditText, c'est vrai par défaut.

Doit être une booleanvaleur, soit trueou false.

Cela peut également être une référence à une ressource (dans le formulaire @[package:]type:name) ou à un attribut de thème (dans le formulaire ?[package:][type:]name) contenant une valeur de ce type.

Cela correspond au symbole de ressource attribut global modifiable.

Méthodes connexes


2

Essayez de remplacer l'écouteur onLongClick du texte d'édition pour supprimer le menu contextuel:

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

3
J'ai utilisé android: editable = "false" et android: focusable = "false", puis j'ai remplacé onLongclick et j'ai obtenu le résultat que je voulais
JannGabriel

2

Utilisez ce code:

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

La désactivation editTextdonne un aspect et un comportement en lecture seule , mais change également le text-colorgris, il est donc nécessaire de définir sa couleur de texte.


Veuillez également ajouter quelques explications.
BlackBeard

1

voici mon implémentation (un peu longue, mais utile pour moi!): Avec ce code vous pouvez rendre EditView Read-only ou Normal. même en lecture seule, le texte peut être copié par l'utilisateur. vous pouvez changer le backgroud pour le rendre différent d'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;
    }
}

l'avantage de ce code est que le EditText est affiché en tant que EditText normal mais le contenu n'est pas modifiable. La valeur de retour doit être conservée en tant que variable pour pouvoir revenir de l'état en lecture seule à l'état normal.

pour rendre un EditText en lecture seule, il suffit de le mettre comme:

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

et pour le rendre normal, utilisez tw de la déclaration précédente:

setReadOnly(editText, false, tw);

1

Cela a fonctionné pour moi, en tenant compte de plusieurs des suggestions ci-dessus. Rend le TextEdit focusable, mais si l'utilisateur clique ou se concentre, nous affichons une liste de sélections dans une PopupWindow. (Nous remplaçons le widget farfelu Spinner). TextEdit xml est très générique ...

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

Si vous souhaitez simplement pouvoir copier du texte à partir du contrôle sans pouvoir le modifier, vous pouvez utiliser un TextView à la place et définir le texte est sélectionnable .

code:

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 documentation de setTextIsSelectable dit:

Lorsque vous appelez cette méthode pour définir la valeur de textIsSelectable, elle définit les indicateurs focusable, focusableInTouchMode, clickable et longClickable sur la même valeur ...

Cependant, j'ai dû définir explicitement focusable et focusableInTouchMode sur true pour le faire fonctionner avec la saisie tactile.


1

C'était la seule solution simple et complète pour moi.

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

0

Je n'ai eu aucun problème à rendre EditTextPreference en lecture seule, en utilisant:

editTextPref.setSelectable(false);

Cela fonctionne bien lorsqu'il est associé à l'utilisation du champ «résumé» pour afficher des champs en lecture seule (utile pour afficher les informations de compte, par exemple). Mise à jour des champs de résumé extraits dynamiquement 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());
        }
    }
}

0

Définissez ceci dans le fichier xml EdiTextView

android:focusable="false"

1
La question demande comment le rendre en lecture seule par programme, pas en XML.
JK7

0

Comme il android:editable=""est obsolète, le

paramètre

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

le rendra "en lecture seule".

Cependant, les utilisateurs pourront toujours coller dans le champ ou effectuer toute autre action de clic long. Pour désactiver cela, remplacez simplement onLongClickListener ().
À Kotlin:

  • myEditText.setOnLongClickListener { true }

suffit.


0

Mon approche à ce sujet a été de créer une classe TextWatcher personnalisée comme suit:

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

Ensuite, vous ajoutez simplement cet observateur à n'importe quel champ que vous souhaitez être en lecture seule malgré son activation:

editText.addTextChangedListener(new ReadOnlyTextWatcher(editText));
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.