web-dev-qa-db-fra.com

Empêche la touche Entrée sur EditText tout en affichant le texte sur plusieurs lignes

Comment créer un texte EditText sur Android, de sorte que l'utilisateur ne puisse pas entrer un texte multiligne, mais que l'affichage soit toujours multiligne (c'est-à-dire que Word-wrap remplace le texte à droite)

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

62

Je sous-classerais le widget et remplacerais la gestion des événements de clé afin de bloquer la clé Enter:

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);
    }
}
46
Tony the Pony

Il s'agit d'une méthode pour laquelle vous n'avez pas à remplacer la classe EditText. Vous attrapez et remplacez les nouvelles lignes par des chaînes vides.

myEditTextObject.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) {

        for(int i = s.length(); i > 0; i--) {

            if(s.subSequence(i-1, i).toString().equals("\n"))
                s.replace(i-1, i, "");
        }

        String myTextString = s.toString();
    }
});
42
Andreas Rudolph

Propriété en XML

Android:lines="5"
Android:inputType="textPersonName"
24
sergey.n

Celui-ci fonctionne pour moi:

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

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

14
soger

La réponse fournie par @Andreas Rudolph contient un bogue critique et ne doit pas être utilisée. Le code provoque une IndexOutOfBoundsException lorsque vous passez du texte à l'intérieur de la EditText qui contient plusieurs caractères de nouvelle ligne. Cela est dû au type de boucle utilisé. L'objet Editable appelle la méthode afterTextChanged dès que son contenu change (remplacer, supprimer, insérer).

Code correct:

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;
            }
        }
    }
});
6
Rolf ツ

Essaye ça:

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_ENTER)
    {
        //Nothing
        return true;
    }
    return super.onKeyDown(keyCode, event);
}
5
Niranj Patel

Je teste cela et cela semble fonctionner:

EditText editText = new EditText(context);
editText.setSingleLine(false);
editText.setInputType(Android.text.InputType.TYPE_CLASS_TEXT | Android.text.InputType.TYPE_TEXT_VARIATION_EMAIL_SUBJECT);
5
Juan Carlos

Vous pouvez le définir à partir du XML comme ceci:

Android:imeOptions="actionDone"
Android:inputType="text"
Android:maxLines="10"

n'oubliez pas Android:inputType="text", si vous ne le définissez pas, cela ne fonctionne pas. Je ne sais pas pourquoi… .. De plus, n'oubliez pas de changer maxLines en votre valeur préférée.

3
Buddy

Ajoutez simplement

        Android:singleLine="true"

à votre EditText

3
Royce Raju Beena

Voici une réponse plus correcte qui n'affiche pas la touche Entrée du 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);

En outre, vous pouvez remplacer setSingleLine(true) par l'un des Android:inputType explicites du fichier de mise en forme XML ou setInputType(InputType.*) du code - dans lequel, le type d'entrée utilisé est tout ce que vous savez limiter l'entrée à une seule ligne seulement (c.-à-d. tout ce qui appelle setSingleLine(true) déjà implicitement).


Explication:

Ce que fait setSingleLine(true) appelle les fonctions setHorizontallyScrolling(true) et setLines(1) implicitement, parallèlement à la modification de certains paramètres du clavier de l'IME pour désactiver la touche Entrée.

À son tour, l'appel à setLines(1) équivaut à appeler setMinLines(1) et setMaxLines(1) en un seul appel.

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

Conclusion:

Donc, pour obtenir ce que le PO veut, nous luttons simplement contre ces paramètres implicites en inversant ces appels implicites.

1
Jason Sparc

La réponse acceptée a tellement bien fonctionné que j'ai copié du texte avec des sauts de ligne dans le texte d'édition. J'ai donc ajouté onTextContextMenuItem pour surveiller l'action de collage.

@Override
public boolean onTextContextMenuItem(int id) {
    boolean ret = super.onTextContextMenuItem(id);
    switch (id) {
        case Android.R.id.paste:
            onTextPaste();
            break;
    }
    return ret;
}

public void onTextPaste() {
    if (getText() == null)
        return;
    String text = getText().toString();
    text = text.replaceAll(System.getProperty("line.separator"), " ");
    text = text.replaceAll("\\s+", " ");
    setText(text);
}
1
Olayinka

Pour un URI vous pouvez utiliser:

Android:inputType="textUri"
Android:lines="1"
Android:maxLength="128"

Autrement, Android:inputType="textPersonName", comme mentionné ci-dessus, fonctionne pour d'autres noms de texte tels que EditText, etc.

0
farid_z

Voici la solution ....

<EditText
   Android:id="@+id/editText"
   Android:layout_width="match_parent"
   Android:layout_height="wrap_content"
   Android:maxLength="150"                                 
   Android:textSize="15dp"
   Android:imeOptions="actionDone"
   Android:inputType="text|textMultiLine"/>

Utilisation en classe Java

editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View view, 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 (keyCode == KeyEvent.KEYCODE_ENTER);
        }
    });
0
priyanka
    EditText textView = new EditText(activity);
    ...
    textView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
            if(KeyEvent.KEYCODE_ENTER == keyEvent.getKeyCode()) {
                return false;
            }
            ....... 

        }
    });
0
Gilad

Vous pouvez changer le bouton d'action du code

editText.imeOptions = EditorInfo.IME_ACTION_DONE
editText.setRawInputType(InputType.TYPE_CLASS_TEXT)

Xml 

Android:inputType="textMultiLine"
0
Ali hasan
<EditText 
  Android:id="@+id/Msg"
  Android:layout_width="fill_parent"
  Android:layout_height="wrap_content"              
  Android:layout_marginTop="5dip"
  Android:lines="5"
  Android:selectAllOnFocus="true"               
  Android:hint="Skriv meddelande...\n(max 100tkn)"/>


EditText et = (EditText)findViewById(R.id.Msg);
String strTmp = et.getText().toString();
strTmp = strTmp.replaceAll("\\n"," ");
0
Anders

Je vais donner une autre option afin que vous n'ayez pas à sous-classe EditText. Créez une InputFilter qui filtre les sauts de ligne. Ensuite, utilisez EditText.addInputFilter.

Le code source pour un tel filtre d’entrée est ici: https://Gist.github.com/CapnSpellcheck/7c72830e43927380daf5205100c93977

Vous pouvez passer 0 dans le constructeur et il n'autorisera aucune nouvelle ligne. En outre, vous pouvez combiner cela avec l'un des autres réglages tels que Android:imeOptions="actionDone", car cela aidera à améliorer l'expérience sur certains appareils.

0
androidguy

Ajouter cette propriété à la variable EditText XML fonctionne pour moi:

Android:lines="1"

Il permet aux utilisateurs de saisir des caractères de nouvelle ligne, mais la hauteur de EditText n’augmente pas.

0
Matthew Quiros