style - input method android edittext




Création d'un SoftKeyboard avec des caractères multiples/alternés par clé (4)

J'ai suivi les exemples sur developer.android.com concernant les méthodes d'entrée et joué avec l'exemple d'application SoftKeyboard . Ceux-ci donnent ensemble plus qu'assez d'informations concernant la création de clavier simple.

Ce que je ne peux pas voir dans l'API est la possibilité de créer des caractères alternatifs / multiples par clé qui est disponible sur le clavier standard (LatinIME Keyboard).

L'image ci-dessus est le résultat d'un appui long sur la touche "a". Lorsque vous appuyez longuement sur une touche, il est possible de remplir une fenêtre avec des caractères alternatifs.

Il est également possible de donner un indice contextuel sur certaines touches qui incitera l'utilisateur à appuyer sur une touche et à la maintenir enfoncée pour accéder au menu contextuel.

Jusqu'à présent, je n'ai pas trouvé une seule source d'informations sur la façon dont cela est réalisé, j'espère que quelqu'un pourra me donner une longueur d'avance, jusque-là je vais suivre le code source du clavier intégré et voir si je peux faire de l'ingénierie inverse il.

Edit: Aiderait si le lien de developer.android.com au clavier LatinIME ne liaient pas à une image d'un Sheep :) Le code source actuel pour LatinIME.java .

Edit 2: Plus comme référence que toute autre chose, c'est la séquence que je crois qu'une action longPress habituelle traverse pour afficher le clavier popup dans KeyboardView.java :

onTouchEvent()
onModifiedTouchEvent()
mHandkler.handleMessage() with MSG_LONGPRESS
openPopupIfRequired() 
onLongPress()

Édition 3:

Je n'ai toujours pas compris cela - Comment ajouter des suggestions d'étiquettes aux clés? Une réponse suggère qu'il n'est pas intégré dans l'API et en effet je n'ai pas trouvé le code pour le faire. Cependant, le clavier sur 2.3.4 (API 10) montre cette fonctionnalité en cours d'implémentation:

Je voudrais vraiment comprendre comment ça se passe, mais ce n'est pas quelque part dans la méthode onDraw() que je peux voir - ce qui me fait croire qu'il est écrit en dehors de l'élément KeyboardView. Je ne peux pas trouver le fichier de layout utilisé pour afficher l'élément KeyboardView sur le clavier intégré - Si quelqu'un sait où trouver cela peut-être que cela me donnera l'indice dont j'ai besoin.

Edit 4: Moved key Aperçu de la question ici car il est légèrement hors sujet:

Comment désactiver la fenêtre d'aperçu de la clé SoftKeyboard?


A en juger par ma propre tentative de codage d'un clavier logiciel, j'ai découvert que:

  • Nice / Bling fonctionnalités nécessite généralement que vous étendez KeyboardView et essentiellement écrire de grandes parties du code de dessin. Malheureusement, vous ne pouvez pas le faire en remplaçant certaines méthodes clés car presque tout est privé. Vous pourriez vouloir jeter un coup d'oeil (et emprunter du code de:
    • (base)/core/java/android/inputmethodservice/KeyboardView.java (code de base android repo)
    • (apps)/other/LatinIME/LatinKeyboardView.java (repo des applications de base Android)

Notez que le mouton sur android.kernel.org est là pour vous dire que le repo est fermé à cause de crackers mais qu'il y a des miroirs du code ailleurs (malheureusement les liens ont été perdus)

  • La base KeyboardView ne prend pas en charge les indications de clé ombrée, vous devez coder votre propre KeyboardView pour avoir une chance de surcharger la méthode onDraw ().

Maintenant, sur ce que vous pouvez faire:

  • Vous pouvez contourner ce problème en fournissant des images pour les clés: utilisez xml <Key ... android:keyIcon="@drawable/this_key_icon_file /> Malheureusement, vous aurez certainement de mauvais résultats pour les lettres avec cette méthode (résolution problèmes).

  • Vous pouvez utiliser (et configurer l'apparence de) clavier contextuel qui apparaît sur une pression longue.

Déclarer un modèle de clavier res/xml/kbd_popup_template.xml :

<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="10%p"
    android:horizontalGap="0px"
    android:verticalGap="0px"
    android:keyHeight="@dimen/key_height">
</Keyboard>

Déclarez les valeurs de chaîne contenant les clés que vous voulez sur ce clavier res/values/strings.xml :

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="alternates_for_a">àáâãäåæ</string>
</ressources>

Ensuite, utilisez les deux dans votre définition de disposition de clavier:

<Key android:codes="97" android:keyLabel="a"  
    android:popupKeyboard="@xml/kbd_popup_template"
    android:popupCharacters="@string/alternates_for_a" />
  • Vous pouvez également utiliser la fonction double-tap, triple-tap, ... pour générer des variantes pour la touche que vous appuyez. Pour ce faire, utilisez simplement une liste pour les codes clés android:

    <Key android:codes="97,224,230" .../>

produira 97 = ' a ' pour un simple tap, 224 = ' à ' pour double tap et 230 = ' æ ' pour triple tap.

La durée à prendre en compte est de 800ms dans le code source android. C'est malheureusement codé en dur (et un peu haut, je pense).

Sachez qu'en tapant deux fois, il envoie en premier un ' a ' en premier, puis, au second clic, il envoie ' à '. Certaines applications ne vont pas aimer ça.


Ce clavier contextuel avec le bouton de fermeture est ennuyeux lorsque nous n'avons qu'un seul caractère contextuel. La manière la plus simple est de remplacer la méthode onLongPress de la classe KeyboardView comme ceci.

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == '1') {
        getOnKeyboardActionListener().onKey('!', null);
        return true;
    }
}

Si vous voulez avoir un texte au-dessus de votre clé, vous pouvez le faire dans la méthode onDraw () de votre classe qui étend KeyboardView. J'ai fait quelque chose comme ça peut-être que cela pourrait aider quelqu'un

 @Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.d("LatinKeyboardView", "onDraw");

    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(30);
    paint.setColor(Color.LTGRAY);

    List<Key> keys = getKeyboard().getKeys();
    for (Key key : keys) {
        if (key.label != null) {
            switch (key.codes[0]) {

                //qQ
                case 81:
                case 113:
                case 1602:
                case 1618:
                    canvas.drawText(String.valueOf(1), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //wW
                case 87:
                case 119:
                case 1608:
                case 1572:
                    canvas.drawText(String.valueOf(2), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //eE
                case 69:
                case 101:
                case 1593:
                case 1617:
                    canvas.drawText(String.valueOf(3), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //rR
                case 82:
                case 114:
                case 1585:
                case 1681:
                    canvas.drawText(String.valueOf(4), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //tT
                case 84:
                case 116:
                case 1578:
                case 1657:
                    canvas.drawText(String.valueOf(5), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //yY
                case 89:
                case 121:
                case 1746:
                case 1552:
                    canvas.drawText(String.valueOf(6), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //uU
                case 85:
                case 117:
                case 1569:
                case 1574:
                    canvas.drawText(String.valueOf(7), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //iI
                case 73:
                case 105:
                case 1740:
                case 1648:
                    canvas.drawText(String.valueOf(8), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //oO
                case 79:
                case 111:
                case 1729:
                case 1731:
                    canvas.drawText(String.valueOf(9), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //pP
                case 80:
                case 112:
                case 1662:
                case 1615:
                    canvas.drawText(String.valueOf(0), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //aA
                case 65:
                case 97:
                case 1575:
                case 1570:
                    canvas.drawText("@", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //sS
                case 83:
                case 115:
                case 1587:
                case 1589:
                    canvas.drawText("#", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //dD
                case 68:
                case 100:
                case 1583:
                case 1672:
                    canvas.drawText("$", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //fF
                case 70:
                case 102:
                case 1601:
                case 1613:
                    canvas.drawText("%", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //gG
                case 71:
                case 103:
                case 1711:
                case 1594:
                    canvas.drawText("&", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //hH
                case 72:
                case 104:
                case 1726:
                case 1581:
                    canvas.drawText("-", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //jJ
                case 74:
                case 106:
                case 1580:
                case 1590:
                    canvas.drawText("+", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //kK
                case 75:
                case 107:
                case 1705:
                case 1582:
                    canvas.drawText("(", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //lL
                case 76:
                case 108:
                case 1604:
                case 1614:
                    canvas.drawText(")", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //zZ
                case 90:
                case 122:
                case 1586:
                case 1584:
                    canvas.drawText("*", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //xX
                case 88:
                case 120:
                case 1588:
                case 1679:
                    canvas.drawText("\"", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //cC
                case 67:
                case 99:
                case 1670:
                case 1579:
                    canvas.drawText("\'", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //vV
                case 86:
                case 118:
                case 1591:
                case 1592:
                    canvas.drawText(":", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //bB
                case 66:
                case 98:
                case 1576:
                case 1616:
                    canvas.drawText(";", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //nN
                case 78:
                case 110:
                case 1606:
                case 1722:
                    canvas.drawText("!", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //mM
                case 77:
                case 109:
                case 1605:
                case 1611:
                    canvas.drawText("?", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


            }

        }

    }
}

ajuster ces axes selon votre choix

int keyXAxis = 25;
int keyYAxis = 50;

Si vous voulez avoir un texte au-dessus de votre clé, vous pouvez le faire dans la méthode onDraw () de votre classe qui remplace KeyboardView

 @Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    ...
    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(18);
    paint.setColor(Color.WHITE);
    //get all your keys and draw whatever you want
    List <Keyboard.Key> keys = getKeyboard().getKeys();
    for(Keyboard.Key key: keys) {
        if(key.label != null) {

            if (key.label.toString().equals("q") || key.label.toString().equals("Q"))
                canvas.drawText(String.valueOf(1), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("w") || key.label.toString().equals("W"))
                canvas.drawText(String.valueOf(2), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("e") || key.label.toString().equals("E"))
                canvas.drawText(String.valueOf(3), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("r") || key.label.toString().equals("R"))
                canvas.drawText(String.valueOf(4), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("t") || key.label.toString().equals("T"))
                canvas.drawText(String.valueOf(5), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("y") || key.label.toString().equals("Y"))
                canvas.drawText(String.valueOf(6), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("u") || key.label.toString().equals("U"))
                canvas.drawText(String.valueOf(7), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("i") || key.label.toString().equals("I"))
                canvas.drawText(String.valueOf(8), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("o") || key.label.toString().equals("o"))
                canvas.drawText(String.valueOf(9), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else if (key.label.toString().equals("p") || key.label.toString().equals("P"))
                canvas.drawText(String.valueOf(0), key.x + (key.width / 2) + 10, key.y + 25, paint);

            else
            {}
        }
    }
}