web-dev-qa-db-fra.com

Comment implémenter Multiline EditText avec le bouton ActionDone (sans bouton Entrée)

J'ai EditText qui est utilisé pour saisir le contenu des messages (e-mails, sms). Je souhaite que le message soit immédiatement publié sur le bouton ActionDone. J'utilise le code suivant pour cela:

message.setOnEditorActionListener((textView, i, keyEvent) -> {
            switch (i) {
                case EditorInfo.IME_ACTION_DONE:
                    if (messageCanBePosted()) {
                        SoftKeyboard.hide(message);
                        postMessage();
                        return true;
                    } else {
                        return false;
                    }
                default:
                    return false;
            }
        }); 

Mais je veux aussi que ce champ de message soit multiligne, comme dans toutes les autres applications de messagerie. Je peux y arriver avec cette ligne:

Android:inputType="textMultiLine"

Le problème est qu'après avoir ajouté cette ligne, le bouton ActionDone commence à agir comme le bouton Enter. Donc, mon rappel pour attraper EditorInfo.IME_ACTION_DONE n'est jamais appelé. Ainsi, chaque fois que l'utilisateur appuie sur ce bouton, le curseur se déplace vers une nouvelle ligne au lieu de publier un message.

Comment puis-je conserver le comportement multiligne de EditText (possibilité d'afficher du texte sur plusieurs lignes) et du bouton ActionDone?

21
Ruslan

Enfin, après avoir recherché ici des fils similaires, j'ai trouvé une solution. Il suffit d'ajouter ces lignes à votre activité/fragment:

editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);

Pour une raison quelconque, cela ne fonctionne pas si vous appliquez exactement le même paramètre à partir de xml. Vous devez le faire par programme.

Il existe également une autre solution possible - dérivez de EditText et appliquez EditorInfo.IME_ACTION_DONE manuellement. Mais pour moi, la première solution semble plus simple.

32
Ruslan

Utilisation

editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);

et en XML:

Android:inputType="textMultiLine"

Source: EditText multiligne avec bouton d'action Terminé

34
Rathi J

Continue Ruslan réponse. L'astuce a fonctionné, mais il y a encore une chose dont vous devez vous occuper en XML.

EditText devrait avoir le type d'entrée text sinon actionDone ne fonctionnera pas. Le type d'entrée par défaut de EditText permet à l'utilisateur de saisir des sauts de ligne, donc inputType doit être défini sur text, c'est-à-dire.

Android:inputType="text"
//And of course
Android:imeOptions="actionDone"

Et dans votre classe Java classe, vous devez ajouter:

editText.setHorizontallyScrolling(false);
16
Noman Rafique

Solution Kotlin réutilisable

La définition de ces valeurs dans le code a fonctionné pour moi, grâce aux autres réponses

edittext.inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
edittext.setHorizontallyScrolling(false)
edittext.maxLines = Integer.MAX_VALUE // Or your preferred fixed value

J'en ai besoin fréquemment, alors faites ceci pour garder le code propre:

fun EditText.multilineIme(action: Int) {
    inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
    horizontalScroll(false)
    maxLines = Integer.MAX_VALUE
}

// Then just call
edittext.multilineIme(EditorInfo.IME_ACTION_DONE)

Si vous souhaitez ajouter une action personnalisée facultative sur "Terminé", essayez ceci:

fun EditText.multilineDone(callback: (() -> Unit) = null) {
    val action = EditorInfo.IME_ACTION_DONE
    multilineIme(action)
    setOnEditorActionListener { _, actionId, _ ->
            if (action == actionId) {
                callback?.invoke()
                true
            }
            false
        }
    }
}

// Then you can call
edittext.multilineDone { closeKeyboard() }

// or just
edittext.multilineDone()
0
Gibolt