web-dev-qa-db-ja.com

キーごとに複数/代替文字を使用したソフトキーボードの作成

developer.Android.com の例に従って 入力メソッド を試し、 SoftKeyboard サンプルアプリケーションを使用しました。これらは一緒になって、単純なキーボードの作成に関する十分な情報を提供します。

APIに表示されないのは、標準のキーボード(LatinIMEキーボード)で使用可能なキーごとに代替/複数の文字を作成する機能です。

enter image description here

上の画像は、「a」キーを長押しした結果です。キーを長押しすると、ポップアップに代替文字を入力することができます。

enter image description here

また、ポップアップメニューを表示するためにユーザーにキーを押したままにするように促すいくつかのキーにポップアップヒントを与えることもできます。

これまで、私はこれがどのように達成されるかについての単一の情報源を見つけていません。うまくいけば、誰かが私に有利なスタートを切ることができます。それまでは、内蔵キーボードのソースコードに従って、それ。

編集:developer.Android.com のLatinIMEキーボードへのリンクが画像にリンクしていなかった場合に役立ちます Sheep :) LatinIME.Java の実際のソースコード。

編集2:これは他の何よりも参考として、これはポップアップキーボードを表示するために通常のlongPressアクションが通過すると信じているシーケンスです- KeyboardView.Java

_onTouchEvent()
onModifiedTouchEvent()
mHandkler.handleMessage() with MSG_LONGPRESS
openPopupIfRequired() 
onLongPress()
_

編集3:

私はまだこれを理解していません-どのようにキーにラベルの提案を追加しますか?答えは、APIに組み込まれていないことを示唆しており、実際にこれを行うためのコードが見つかりませんでした。ただし、2.3.4(API 10)のキーボードには、この機能が実装されていることが示されています。

enter image description here

ITがそれをどのように行うかを非常に理解したいと思いますが、onDraw()メソッドのどこにも表示されていないため、KeyboardView要素の外部で記述されていると思われます。ただし、組み込みキーボードでKeyboardView要素を表示するために使用されるlayoutファイルが見つかりません。これを見つける場所を誰かが知っている場合、おそらく必要な手がかりが得られます。

編集4:トピックから少し外れているため、キーをプレビューする質問をここに移動しました:

SoftKeyboardキープレビューウィンドウを無効にする方法

43
Graeme

代替キーのポップアップの実装:

ポップアップキーボードを使用する各キーについて、 popupCharacters および popupKeyboard を定義する必要があります。

/res/xml/[Keyboard].xml

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

popupKeyboardは、代替キーを含むポップアップで使用されるキーボードのXML表現です。

/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>

代替キーポップアップのスタイル設定:

ポップアップのレイアウト/スタイル(デフォルトは @ Android:layout/keyboard_popup_keyboard.xml )を変更する場合は、レイアウトファイルを指すAndroid:popupLayout属性を指定できます。

<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" />

キープレビューオーバーレイの実装:

キープレビューを表示するために一緒にノックすることができた唯一のソリューション(KeyboardViewのソースコードを完全に書き換えることなく)は以下のとおりです。

<KeyboardView>タグを<FrameLayout>でラップし、keyHeightに行数を掛けて高さを指定します。このタグ内で、行を保持するLinearLayoutを作成し、各<Key>に指定された%p値に等しい重みを持つTextViewを含む各行のLinearLayoutを作成しました。

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

そしてスタイル:

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

これはこれを生成します:

enter image description here

システムキーボードと同じ方法でこれを実装するまで、私は満足しません!

51
Graeme

ソフトキーボードをコーディングしようとする私自身の試みから判断すると、次のことがわかりました。

  • Nice/bling機能を使用するには、通常KeyboardViewを拡張し、基本的に描画コードの大部分を記述する必要があります。残念ながら、ほとんどすべてがプライベートであるため、いくつかのキーメソッドをオーバーライドしてcannotできません。あなたは見てみたいと思うかもしれません(そしていくつかのコードを借ります:
    • (base)/core/Java/Android/inputmethodservice/KeyboardView.Java(Androidコアコードリポジトリ)
    • (apps)/other/LatinIME/LatinKeyboardView.Java(Androidコアアプリリポジトリ)

Android.kernel.orgの羊は、クラッカーが原因でリポジトリが閉じられているが、他の場所にコードのミラーがある(残念ながらリンクを失った)ことを伝えるためにあります。

  • ベース KeyboardView には、シャドウキーヒントのnoサポートがあります。独自のKeyboardViewをコーディングして、 onDraw()メソッドをオーバーライドする機会。

さあ、あなたはcanができることについて

  • キーの画像を提供することで、この問題を回避できます:use xml <Key ... Android:keyIcon="@drawable/this_key_icon_file /> このため。残念ながら、この方法を使用した場合、レターの結果はほとんど間違いなくあります(解決の問題)。

  • 長押しで表示されるポップアップキーボードを使用(および外観を構成)できます。

キーボードテンプレートを宣言する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>

このキーボードで必要なキーを含む文字列値を宣言しますres/values/strings.xml

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

次に、キーボードレイアウト定義で両方を使用します。

<Key Android:codes="97" Android:keyLabel="a"  
    Android:popupKeyboard="@xml/kbd_popup_template"
    Android:popupCharacters="@string/alternates_for_a" />
  • ダブルタップ、トリプルタップ、...機能を使用して、タップするキーの代替を生成することもできます。そのためには、Android keycodesにlistを使用します:

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

シングルタップの場合は97 = 'a'、224 = 'à 'ダブルタップの場合は230 =' æ 'トリプルタップ。

ダブルタップを考慮する期間は、Androidソースコードで800ミリ秒に設定されています。残念ながらハードコードされています(少し高いと感じます)。

ダブルタップすると、基本的に 'a'が最初に送信され、次に2回目のタップで 'à '。一部のアプリは、これが好きではありません。

14
Laurent'

閉じるボタンを備えたポップアップキーボードは、ポップアップ文字が1つしかない場合に迷惑です。より簡単な方法は、このようにKeyboardViewクラスのonLongPressメソッドをオーバーライドすることです。

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

キーの上にテキストを配置したい場合は、KeyboardViewをオーバーライドするクラスのonDraw()メソッドでそれを実行できます。

 @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

ビュー領域の外側をタップしてポップアップキーボードを閉じようとする人のために、TouchListenerを拡張するクラス内のKeyboardViewInputMethodServiceを追加することで運が良かった

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

キーの上にテキストを置きたい場合は、KeyboardViewを拡張するクラスのonDraw()メソッドでそれを行うことができます

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;


            }

        }

    }
}

選択に応じてこれらの軸を調整します

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