web-dev-qa-db-fra.com

Création d'un SoftKeyboard avec des caractères multiples/alternatifs par touche

J'ai suivi les exemples de developer.Android.com concernant méthodes de saisie et joué avec l'exemple d'application SoftKeyboard . Ensemble, ils fournissent plus d’informations sur la création d’un clavier simple.

Ce que je ne vois pas dans l'API, c'est la possibilité de créer des caractères alternatifs/multiples par touche disponibles sur le clavier standard (clavier LatinIME).

enter image description here

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 contextuelle avec des caractères différents.

enter image description here

Il est également possible de donner un indice contextuel sur certaines touches, ce qui incitera l'utilisateur à appuyer longuement sur une touche pour afficher le menu contextuel.

Jusqu'à présent, je n'ai trouvé aucune source d'information sur la manière dont cela est réalisé. J'espère que quelqu'un pourra me donner une longueur d'avance. Jusque-là, je suivrai le code source du clavier intégré et verrai si je peux faire de l'ingénierie inverse. il.

Edit: Cela aiderait si le lien de developer.Android.com vers le clavier LatinIME ne renvoyait pas à une image d'un Sheep :) Code de code source réel de LatinIME.Java .

Edit 2: Plus comme référence qu'autre chose, il s'agit de la séquence, je crois, d'une action longPress habituelle afin d'afficher le clavier contextuel dans KeyboardView.Java :

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

Edit 3: 

Je n'ai toujours pas compris cela - Comment ajoutez-vous des suggestions d'étiquettes aux clés? Une réponse suggère que cela ne fait pas partie de l'API et, en fait, je n'ai pas trouvé le code pour le faire. Cependant, le clavier sous 2.3.4 (API 10) montre que cette fonctionnalité est implémentée:

enter image description here

Voudrais vraiment comprendre comment cela fonctionne, mais ce n’est nulle part dans la méthode onDraw() que je peux voir - ce qui me fait penser que c’est écrit en dehors de l’élément KeyboardView. Cependant, je ne trouve pas le fichier layout utilisé pour afficher l'élément KeyboardView sur le clavier intégré - Si quelqu'un sait où trouver ceci, cela me donnera peut-être l'indice dont j'ai besoin.

Edit 4: Clé déplacée Prévisualisez ici la question d’aperçu car elle est légèrement en retrait du sujet:

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

43
Graeme

Mise en œuvre d'une fenêtre contextuelle de clé alternative:

Vous devez définir popupCharacters et popupKeyboard :

/res/xml/[Keyboard].xml

<Key Android:keyLabel="("
    Android:popupKeyboard="@xml/keyboard_popup_template"
    Android:popupCharacters="[{&lt;" />

popupKeyboard est une représentation XML du clavier utilisé dans la fenêtre contextuelle contenant les touches de remplacement:

/res/xml/keyboard_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="56dp">
</Keyboard>

Mise en forme de la clé alternative:

Si vous souhaitez modifier la présentation/le style de la fenêtre contextuelle (par défaut, @Android: layout/keyboard_popup_keyboard.xml ), vous pouvez spécifier un attribut Android:popupLayout qui pointe vers un fichier de présentation

<Android.inputmethodservice.KeyboardView
    Android:id="@+id/keyboard"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:layout_alignParentBottom="true"
    Android:background="#FF272727"
    Android:popupLayout="@layout/keyboard_popup_keyboard" />

Implémentation de la superposition de l'aperçu de la clé:

La seule solution que j'ai pu associer pour afficher des aperçus clés (sans réécrire entièrement le code source de KeyboardView) est la suivante:

Enveloppant la balise <KeyboardView> avec un <FrameLayout> avec une hauteur spécifiée en multipliant le keyHeight par le nombre de lignes. À l'intérieur de cette balise, j'ai simplement créé un LinearLayout pour contenir des lignes, puis un LinearLayout pour chaque ligne contenant un TextView avec un poids égal à la valeur% p spécifiée pour chaque <Key>:

<TextView Android:text="!" style="@style/Custom.Widget.KeyboardKeyOverlay"  Android:layout_width="0dp" Android:layout_height="wrap_content" Android:layout_weight="10"/>

Et stylé:

<style name="CustomTheme.Widget.KeyboardKeyOverlay">
    <item name="Android:background">@Android:color/transparent</item>
    <item name="Android:textColor">#FFAAAAAA</item>
    <item name="Android:paddingRight">6dp</item>
    <item name="Android:paddingTop">4dp</item>
    <item name="Android:textSize">10sp</item>
    <item name="Android:gravity">right</item>
    <item name="Android:textStyle">bold</item>
</style>         

Qui produit ceci:

enter image description here

Je ne serai pas heureux tant que je n'aurai pas réussi à implémenter cela de la même manière que le clavier système!

51
Graeme

Ce clavier contextuel avec le bouton de fermeture est ennuyeux lorsque nous n’avons qu’un seul caractère contextuel . Un moyen plus simple consiste à remplacer la méthode onLongPress de la classe KeyboardView de cette manière.

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

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
            {}
        }
    }
}
7
Fedor Tsyganov

Pour tous ceux qui tentent de masquer le clavier contextuel en tapant hors de son champ de vision, j'ai eu un peu de chance en plaçant une variable TouchListener dans la variable KeyboardView de la classe qui s'étendait InputMethodService

public class YourIME extends InputMethodService{
    @Override 
    public View onCreateInputView() {
        mInputView = (LatinKeyboardView) getLayoutInflater().inflate(R.layout.input, null);
        setLatinKeyboard(mQwertyKeyboard);

        mInputView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {

                if(motionEvent.getAction() == MotionEvent.ACTION_DOWN) {                        
                    mInputView.closing(); // Close popup keyboard if it's showing
                }
                return false;
            }
        });

        return mInputView;
    }
// The rest of your ime ...
}
5
Sammy T

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

 enter image description here

 @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;


            }

        }

    }
}

ajustez ces axes selon votre choix 

int keyXAxis = 25;
int keyYAxis = 50;
0
Mateen Chaudhry