Existe-t-il un moyen d'avoir une EditText
à plusieurs lignes présente et d'utiliser le libellé Action IME "Terminé" sur Android 2.3?
Dans Android 2.2, ce n’est pas un problème, le bouton Entrée affiche l’étiquette d’action IME "Terminé" (Android:imeActionLabel="actionDone"
) et supprime la saisie logicielle lorsque vous cliquez dessus.
Lors de la configuration d'une EditText
pour plusieurs lignes, Android 2.3 supprime la possibilité d'afficher l'action "Terminé" pour le clavier de saisie logicielle.
J'ai réussi à modifier le comportement du bouton Entrée de saisie logicielle en utilisant une variable KeyListener
, mais le bouton Entrée ressemble toujours à une touche Entrée.
Voici la déclaration du EditText
<EditText
Android:id="@+id/Comment"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="10dp"
Android:layout_marginBottom="0dp"
Android:lines="3"
Android:maxLines="3"
Android:minLines="3"
Android:maxLength="60"
Android:scrollHorizontally="false"
Android:hint="hint"
Android:gravity="top|left"
Android:textColor="#888"
Android:textSize="14dp"
/>
<!-- Android:inputType="text" will kill the multiline on 2.3! -->
<!-- Android:imeOptions="actionDone" switches to a "t9" like soft input -->
Lorsque je vérifie la valeur inputType
après le chargement de la définition du contenu dans l'activité, elle s'affiche comme suit:
inputType = 0x20001
Lequel est:
TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_NORMAL
InputType.TYPE_TEXT_FLAG_MULTI_LINE
Après avoir relu les documents TextView
et EditorInfo
, il est désormais clair que la plate-forme va forcer IME_FLAG_NO_ENTER_ACTION
pour les affichages de texte multiligne.
Notez que
TextView
sera automatiquement régler ce drapeau pour vous sur plusieurs lignes vues de texte.
Ma solution consiste à sous-classer EditText
et à ajuster les options IME après avoir laissé la plate-forme les configurer:
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection connection = super.onCreateInputConnection(outAttrs);
int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
// clear the existing action
outAttrs.imeOptions ^= imeActions;
// set the DONE action
outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
}
if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
return connection;
}
Dans ce qui précède, je force aussi IME_ACTION_DONE
, même si cela peut être réalisé grâce à une configuration de mise en page fastidieuse.
La réponse d'Ohhorob est fondamentalement correcte, mais son code est vraiment redondant! C'est fondamentalement l'équivalent de cette version beaucoup plus simple (code complet pour les lecteurs paresseux):
package com.example.views;
import Android.content.Context;
import Android.util.AttributeSet;
import Android.view.inputmethod.EditorInfo;
import Android.view.inputmethod.InputConnection;
import Android.widget.EditText;
// An EditText that lets you use actions ("Done", "Go", etc.) on multi-line edits.
public class ActionEditText extends EditText
{
public ActionEditText(Context context)
{
super(context);
}
public ActionEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public ActionEditText(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs)
{
InputConnection conn = super.onCreateInputConnection(outAttrs);
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
return conn;
}
}
Notez que certaines options inputType
telles que textShortMessage
font que cela ne fonctionne pas! Je vous suggère de commencer par inputType="text"
. Voici comment vous pouvez l'utiliser dans votre XML.
<com.example.views.ActionEditText
Android:id=...
Android:layout_stuff=...
Android:imeOptions="actionDone"
Android:inputType="textAutoCorrect|textCapSentences|textMultiLine"
Android:maxLines="3" />
Une autre solution pour sous-classer la classe EditText consiste à configurer votre instance EditText avec ceci:
editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);
Au moins, cela fonctionne pour moi sur Android 4.0. Il configure l'instance EditText de sorte que l'utilisateur modifie une chaîne à une ligne affichée avec un ajustement progressif sur plusieurs lignes, même si une action IME est définie.
Suite de la réponse précédente
public class MultiLineText extends EditText {
public MultiLineText(Context context) {
super(context);
}
public MultiLineText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MultiLineText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
InputConnection connection = super.onCreateInputConnection(outAttrs);
int imeActions = outAttrs.imeOptions&EditorInfo.IME_MASK_ACTION;
if ((imeActions&EditorInfo.IME_ACTION_DONE) != 0) {
// clear the existing action
outAttrs.imeOptions ^= imeActions;
// set the DONE action
outAttrs.imeOptions |= EditorInfo.IME_ACTION_DONE;
}
if ((outAttrs.imeOptions&EditorInfo.IME_FLAG_NO_ENTER_ACTION) != 0) {
outAttrs.imeOptions &= ~EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
return connection;
}
}
Utilisez ceci comme
<myapp.commun.MultiLineText
Android:id="@+id/textNotes"
Android:layout_height="wrap_content"
Android:minHeight="100dp"
Android:layout_width="wrap_content"
Android:hint="Notes"
Android:textSize="20sp"
Android:padding="7dp"
Android:maxLines="4"/>
pour mettre l'action terminée, vous pouvez utiliser:
XML
Android:inputType="text|textCapSentences"
Java
editText.setHorizontallyScrolling(false);
editText.setMaxLines(Integer.MAX_VALUE);
J'espère que ça marchera pour vous.
Apparemment, la réponse à la question initiale est Oui, mais je pense que l’équipe Android essaie de faire réfléchir les développeurs à la façon dont ils utilisent le multi-ligne EditText. Ils veulent que la touche Entrée ajoute des nouvelles lignes et s'attendent probablement à ce que vous fournissiez un bouton ou un autre moyen de saisie pour déclencher l'événement que vous avez terminé de modifier.
J'ai le même problème et ma solution évidente consistait simplement à ajouter un bouton Terminé et à laisser le bouton Entrée ajouter les nouvelles lignes.
Utilisez ces attributs dans votre XML.
Android: inputType = "textImeMultiLine"
Android: imeOptions = "actionDone"