web-dev-qa-db-fra.com

Comportement des imeOptions, imeActionId et imeActionLabel

Je suis assez nouveau pour Android développement natif, et j'essaie de comprendre comment personnaliser les boutons d'action IME. J'ai regardé la documentation de Google, mais je peux en trouver très peu des informations sur le comportement attendu.

D'après le guide officiel je comprends que le bouton d'action du clavier peut être configuré en utilisant les attributs:

  • Android: imeOptions peut définir le texte/id du bouton affiché près de la touche espace sur certaines valeurs prédéfinies (par exemple actionGo définir l'étiquette de la clé sur = Allez et l'id à 2)
  • Android: imeActionLabel définit le libellé du bouton affiché dans la zone de saisie lorsque le clavier est en plein écran, généralement en mode paysage. Peut être défini sur n'importe quelle valeur de chaîne.
  • Android: imeActionId identique à la précédente mais définit l'ID numérique transmis à la méthode de rappel

Mais après quelques tentatives empiriques, j'ai trouvé un comportement différent entre le niveau d'API 15 et les niveaux d'API suivants.

J'ai mis en place un simple élément EditText avec les attributs suivants:

<EditText
        ...
        Android:imeOptions="actionGo"
        Android:imeActionLabel="Custom"
        Android:imeActionId="666"
        Android:inputType="text"/>

et j'ai vérifié l'effet avec les différents niveaux d'API en mode portrait et paysage. Voici le résultat.

API niveau 15 - 4.0.3

En mode portrait, le libellé de la clé est Allez et l'ID d'action transmis à la méthode de rappel est 2, conformément au paramètre imeOptions.

En mode paysage, l'étiquette/l'identifiant de la clé est Allez/2 comme mode portrait, tandis que le bouton affiché dans la zone de saisie est Personnalisé/666, conformément à les attributs imeActionLabel et imeActionId.

API niveau 16, 17 et 18 - 4.1.2, 4.2.2 et 4.3

En mode portrait et paysage, la clé et le bouton sont affichés avec une étiquette Personnalisée et sont liés à 666 id, en ignorant l'attribut imeOptions.

Ce décalage dans le comportement est assez ennuyeux car:

  • avec le niveau API> = 16, vous ne pouvez pas faire la distinction entre le bouton clé et le bouton de la zone de saisie
  • avec le niveau API = 15, vous ne pouvez pas définir de texte personnalisé pour le bouton clé.

Savez-vous comment l'obtenir à la fois dans les API 15 et 16+? Ou s'il existe un moyen d'obtenir un comportement cohérent dans toutes (ou au moins une partie) des versions d'API?

Peut-être que je manque quelque chose dans les paramètres IME qui peut justifier le comportement différent ...

Merci beaucoup!

44
Alessandro

C'est en fait à l'application de méthode d'entrée, et non au framework Android lui-même, de décider quoi faire avec les valeurs que vous définissez.

Le cadre Android transmet simplement les valeurs que vous définissez à la méthode de saisie, qui peut ensuite choisir les boutons à afficher sur le clavier ou un EditText "extrait" en mode plein écran. Le cadre Android influence le EditorInfo de deux manières: -

  • Il le fait passer par EditorInfo.makeCompatible pour s'assurer que les valeurs qu'il contient sont compatibles entre le clavier et l'application targetApiVersion. Pour le moment, cela n'affecte que certaines valeurs de InputType, pas l'action de l'éditeur, mais cela pourrait changer si de nouvelles actions de l'éditeur (ou des paramètres complètement nouveaux) sont introduites.

  • Il définit le comportement par défaut pour la méthode d'entrée, y compris le comportement autour des éditeurs plein écran. Si la méthode d'entrée choisit de ne pas remplacer ce comportement par défaut, elle pourrait se retrouver avec un comportement différent entre les versions Android. De nombreux claviers choisissent de définir leur propre comportement, d'une manière cohérente entre les versions Android.

Pour cette raison, il n'est pas si simple de dire qu'un certain champ EditorInfo a un certain effet sur une version donnée, et il n'y a aucun moyen d'assurer un comportement cohérent, même sur une version Android. Tout ce que vous faites est de fournir des astuces à la méthode de saisie, qui choisit comment les présenter à l'utilisateur.

8
Dan Hulme

Appelez simplement .setImeActionLabel() par programmation dans les codes Java) pour obtenir (à nouveau) l'actionID à votre choix.

editText.setImeActionLabel(getString(R.string.xxx), EditorInfo.IME_ACTION_GO);
10
Cloudream

Lorsque vous démarrez un nouveau projet Android Android, il fournit un bon indice à votre question. Il existe une activité appelée LoginActivity que vous pouvez créer comme écran de connexion par défaut. Cette activité produire un EditText comme suit:

            <EditText
                    Android:id="@+id/password"
                    Android:layout_width="match_parent"
                    Android:layout_height="wrap_content"
                    Android:hint="@string/Prompt_password"
                    Android:imeActionId="@+id/login"
                    Android:imeActionLabel="@string/action_sign_in_short"
                    Android:imeOptions="actionUnspecified"
                    Android:inputType="textPassword"
                    Android:maxLines="1"
                    Android:singleLine="true"/>

Maintenant, si vous lisez documentation , vous saurez que l'attribut imeOptions vous permet de spécifier des actions supplémentaires pour un champ de texte. Par exemple, le clavier qui apparaît a une action dans le coin inférieur droit comme "Suivant". En utilisant imeOptions, vous pouvez sélectionner une autre action dans une liste prédéfinie fournie par Android. Vous pouvez spécifier quelque chose comme "actionSend" ou "actionSearch".

Une fois que vous avez fait cela, pour votre activité, vous pouvez écouter cette action en utilisant le gestionnaire d'événements setOnEditorActionListener:

    mPasswordView = (EditText) findViewById(R.id.password);
    mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
            if (id == R.id.login || id == EditorInfo.IME_NULL) {
                attemptLogin();
                return true;
            }
            return false;
        }
    });

Remarquez comment nous ciblons le imeActionId ici. Il s'agit d'une autre méthode pour cibler ce EditText dans votre activité, tout en ayant la possibilité de modifier l'action sur la saisie au clavier.

2
Donato

Si quelqu'un crée un clavier personnalisé pour Android et a un problème avec le libellé de la touche Entrée, vous devez procéder comme suit. Dans l'exemple de Android clavier personnalisé, nous avons la méthode suivante dans SoftKeyboard.Java:

@Override
    public void onStartInput(EditorInfo attribute, boolean restarting)
    {
        super.onStartInput(attribute, restarting);
.
. // the implementation
. 
        mCurKeyboard.setImeOptions(getResources(), attribute.imeOptions);
    }

Remplacez la dernière ligne par la ligne suivante:

mCurKeyboard.setImeOptions(getResources(), attribute);

Maintenant, dans LatinKeyboard.Java, changez la méthode setImeOptions comme ci-dessous:

void setImeOptions(Resources res, EditorInfo ei)
    {
        if (mEnterKey == null)
        {
            return;
        }

        switch (ei.imeOptions & (EditorInfo.IME_MASK_ACTION | EditorInfo.IME_FLAG_NO_ENTER_ACTION))
        {
            case EditorInfo.IME_ACTION_SEND:
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = res.getText(R.string.label_send_key);
                break;
            case EditorInfo.IME_ACTION_GO:
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = res.getText(R.string.label_go_key);
                break;
            case EditorInfo.IME_ACTION_NEXT:
                mEnterKey.iconPreview = null;
                mEnterKey.icon = null;
                mEnterKey.label = res.getText(R.string.label_next_key);
                break;
            case EditorInfo.IME_ACTION_SEARCH:
                mEnterKey.icon = res.getDrawable(R.drawable.sym_keyboard_search);
                mEnterKey.label = null;
                break;
            default:
                mEnterKey.iconPreview = null;
                mEnterKey.label = res.getText(R.string.label_enter_key);
                mEnterKey.icon = null;
                break;
        }

        if (ei.actionLabel != null)
        {
            mEnterKey.iconPreview = null;
            mEnterKey.icon = null;
            mEnterKey.label = ei.actionLabel;
        }
    }

Maintenant, votre clavier personnalisé affiche une étiquette appropriée en fonction de ce qui est défini dans le fichier xml pour imeActionLabel.

2
Hamid