75 votes

Empêcher l'utilisation de la touche d'entrée dans l'EditText tout en affichant le texte sur plusieurs lignes

Comment puis-je créer un EditText sur Android de telle sorte que l'utilisateur ne puisse pas saisir un texte sur plusieurs lignes, mais que l'affichage soit tout de même sur plusieurs lignes (c'est-à-dire qu'il y ait un retour à la ligne au lieu que le texte se déplace vers la droite) ?

C'est similaire à l'application SMS intégrée où nous ne pouvons pas saisir de nouvelle ligne mais où le texte est affiché sur plusieurs lignes.

11 votes

Ajoutez simplement Android:inputType="textPersonName" à l'EditText pour l'empêcher d'appuyer sur la touche Entrée.

49voto

Tony the Pony Points 13235

Il faudrait sous-classer le widget et modifier le traitement des événements de la clé afin de bloquer l'action de l'utilisateur. Enter clé :

class MyTextView extends EditText
{
    ...
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event)
    {
        if (keyCode==KeyEvent.KEYCODE_ENTER) 
        {
            // Just ignore the [Enter] key
            return true;
        }
        // Handle all other keys in the default way
        return super.onKeyDown(keyCode, event);
    }
}

4 votes

Cette ligne devrait : return super.onKeyDown(keyCode, event); dans onKeyDown ou je me trompe ? :P

0 votes

Nous travaillons tous les deux pour la même communauté. De rien, Jen :)

11 votes

Merci pour votre réponse. (J'ai aussi augmenté l'autre réponse). Astuce : vous pouvez éviter de sous-classer en utilisant simplement editText.setOnKeyListener(...) et return (keyCode == KeyEvent.KEYCODE_ENTER).

49voto

Andreas Rudolph Points 303

Il s'agit d'une méthode pour laquelle il n'est pas nécessaire de remplacer la classe EditText. Il suffit d'attraper et de remplacer les nouvelles lignes par des chaînes vides.

edittext.addTextChangedListener(new TextWatcher() {

public void onTextChanged(CharSequence s, int start, int before, int count) {

}

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

public void afterTextChanged(Editable s) {
    /*
     * The loop is in reverse for a purpose,
     * each replace or delete call on the Editable will cause
     * the afterTextChanged method to be called again.
     * Hence the return statement after the first removal.
     * http://developer.android.com/reference/android/text/TextWatcher.html#afterTextChanged(android.text.Editable)
     */
    for(int i = s.length()-1; i >= 0; i--){
        if(s.charAt(i) == '\n'){
            s.delete(i, i + 1);
            return;
        }
    }
}
});

Crédit à Rolf pour l'amélioration d'une réponse antérieure.

3 votes

+1 Ceci était plus utile dans mon cas que la réponse acceptée, pour la simple raison que je peux l'utiliser comme une implémentation par défaut de TextWatcher, qui peut être étendue par des sous-classes (qui appelleraient alors simplement super.afterTextChanged(...) pour conserver cette vérification des sauts de ligne. Fonctionne !

1 votes

La condition pour la boucle devrait être i > 0 plutôt que i >= 0 . Quand i == 0 , s.subSequence(i-1, i) obtient un IndexOutOfBoundsException .

2 votes

Je pense que cela déclenche une exception IndexOutOfBoundsException pour un texte avec une nouvelle ligne qui est copié et collé avec plusieurs caractères de nouvelle ligne.

23voto

snayde Points 149

Propriété en XML

android:lines="5"
android:inputType="textPersonName"

0 votes

Merci, le plus simple ! Bien que j'ai remarqué que cela empêchait mon écouteur de clics sur l'ET de fonctionner... alors utilisez editText.setSingleLine(false); à la place si c'est le cas.

0 votes

Cela dépend totalement du clavier utilisé. Beaucoup d'entre eux affichent toujours une touche d'entrée

14voto

soger Points 96

Celui-là marche pour moi :

<EditText
    android:inputType="textShortMessage|textMultiLine"
    android:minLines="3"
    ... />

Il affiche un smiley au lieu de la touche Entrée.

2 votes

Par expérience, cela ne fonctionne pas sur tous les claviers. Un téléphone HTC que nous avions autour de nous affichait toujours la touche Entrée.

0 votes

Cela dépend totalement du clavier utilisé. Beaucoup d'entre eux affichent toujours une touche d'entrée

0 votes

Si vous appuyez longuement sur le bouton smiley d'un Nexus 6, vous pouvez toujours ajouter un saut de ligne. Il ne s'agit donc pas d'une solution générale.

9voto

Jason Sparc Points 662

Voici une réponse plus correcte qui n'affiche pas la touche Entrée sur le clavier IME :

// IMPORTANT, do this before any of the code following it
myEditText.setSingleLine(true);

// IMPORTANT, to allow wrapping
myEditText.setHorizontallyScrolling(false);
// IMPORTANT, or else your edit text would wrap but not expand to multiple lines
myEditText.setMaxLines(6);

Vous pouvez également remplacer setSingleLine(true) avec soit, un android:inputType sur le fichier de mise en page XML, ou setInputType(InputType.*) sur le code - dans lequel, le type d'entrée utilisé, est tout ce que vous savez restreindre l'entrée à une seule ligne (c'est-à-dire, tout ce qui appelle setSingleLine(true) implicitement déjà).


Explication :

Quoi setSingleLine(true) fait est d'appeler setHorizontallyScrolling(true) y setLines(1) implicitement, ainsi que la modification de certains paramètres du clavier IME pour désactiver la touche entrée.

À son tour, l'appel à setLines(1) c'est comme appeler setMinLines(1) y setMaxLines(1) en un seul appel.

Certains types d'entrée (c'est-à-dire les constantes de InputType.TYPE_* ) appelle setSingleLine(true) implicitement, ou du moins obtient le même effet.

Conclusion :

Donc, pour réaliser ce que le PO veut, nous controns simplement ces paramètres implicites en annulant ces appels implicites.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X