Androidカスタムキーボードの作成

32401 ワード

原文タイトル:CreateA Custom Keyboard on Android
テキストリンク:http://code.tutsplus.com/tutorials/create-a-custom-keyboard-on-android–cms-22615
Android创建自定义键盘_第1张图片
ほとんどのAndroidデバイスには物理的なキーボードがありません.代わりに、これらのデバイスはソフトキーボードを使用してユーザーの入力を受けています.Androidの個性的な開発に興味があれば、カスタムのソフトキーボードを作成すると、別の新しい高さに連れて行くと信じています.Android SDKを使用すると、認識キーのtouchイベント、キーボードの描画、キーボードと入力ボックスのつながりなど、多くの低レベルのタスクを担当するため、少ないコードでソフトキーボードを迅速に作成できます.
予備知識
eclipse ADTが必要ですが、Android studioを使用することをお勧めします[loader注]
新規プロジェクトの作成
新しいプロジェクトを作成します.SimpleKeyboardで、唯一のパッケージ名を付けたことを保証します.minimum required SDKはAndroid 2.2、target SDKはAndroid 4.4に設定されています.私たちのプロジェクトにはactivityがないので、Create Activityを選択する必要はありません.finishをクリックします.
マニフェストファイルの編集
ソフトキーボードはAndroidシステムによってInput Method Editor(IME)と見なされ、IMEはAndroidManifestにある.xmlではServiceとして定義され、BIND_INPUT_METHODの権限を使用し、android.view.InputMethod actionを追加する必要がある.アプリケーションノードの下にコードを追加すると、
<service android:name=".SimpleIME" android:label="@string/simple_ime" android:permission="android.permission.BIND_INPUT_METHOD" >
    <meta-data android:name="android.view.im" android:resource="@xml/method"/>
    <intent-filter>
        <action android:name="android.view.InputMethod" />
    </intent-filter>
</service>

methodを作成する.xml
上記のプロファイルにはservicemeta-datamethod.xmlのファイルを参照しています.このファイルがなければ、Androidシステムは私たちのserviceを有効なIMEと見なすことはありません.このファイルには入力法とそのsubtypeの説明が含まれています.私たちのキーボードについては、単一のen_USの英語キーボードを定義しています.プロジェクトにres/xmlディレクトリがない場合は、それを作成し、method.xmlをこのディレクトリに追加します.このファイルの内容は次のとおりです.
<?xml version="1.0" encoding="utf-8"?>
<input-method xmlns:android="http://schemas.android.com/apk/res/android">
    <subtype  android:label="@string/subtype_en_US" android:imeSubtypeLocale="en_US" android:imeSubtypeMode="keyboard" />
</input-method>

stringsを編集xml
次のように3つのstringが必要です
  • 当アプリの名称
  • 入力方式のラベル
  • 入力メソッドサブクラスのラベル
  • strings.xmlファイルの内容は以下の通りです.
    <resources>
        <string name="app_name">SimpleKeyboard</string>
        <string name="simple_ime">Simple IME</string>
        <string name="subtype_en_US">English (US)</string>
    </resources>

    キーボードレイアウトの作成
    キーボードのレイアウトには、KeyboardViewlayout_alignParentBottom=trueのプロパティが含まれており、キーボードが常に画面の下部に表示されることを保証します.res/layout/keyboard.xmlファイルを作成し、次のように編集します.
    <?xml version="1.0" encoding="UTF-8"?>
    <android.inputmethodservice.KeyboardView  xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/keyboard" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:keyPreviewLayout ="@layout/preview" />
    keyPreviewLayoutとは、キーボードのキーをクリックするたびに、一時的にポップアップされるレイアウトを指します.res/layout/preview.xmlを作成します.その内容は次のとおりです.
    <?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:background="#ffff00" android:textStyle="bold" android:textSize="30sp" >
    </TextView>

    キーボードを定義するキー
    キーボード上のキーの詳細とその位置xmlファイルに指定します.各キーには次のプロパティがあります.
  • keyLabelこの属性は、各キーが表示するテキスト
  • を指す.
  • codesこの属性は、このキーが表す文字のunicode
  • を指す.
    たとえば、codes属性の値が97keyLabel属性の値がAであるアルファベットAを定義します.1つのcodeが複数のkeyに対応する場合、このkeyが表す文字は、このkeyが受信したクリック数tapsに依存する).例えば、1つのキーは63,33,58符号化を有し、
  • 一度クリックすると?
  • の2回のクリックは!
  • 3回クリックすると
  • 1つのkeyにはオプションのプロパティもあります.
  • keyEdgeFlagsこの属性の値は、leftまたはrightであってもよく、この属性は通常、1行の最も左および最も右のキーに加算される.
  • keyWidthこのプロパティは、キーの幅を定義し、通常はパーセントの値です.
  • isRepeatableという属性がtrueに設定されている場合、このキーを長押しするとそのキーにかかる動作が繰り返し受け入れられ、 キーおよび キーでは通常trueに設定される.

  • キーボード上のキーはすべて行ごとにグループ化されており、通常は各行のキーを10個以内に制限し、各キーはキーボード幅全体の10%を占めています.キーの高さを60 dpに設定します.この値は調整できますが、48 dp未満の設定はお勧めしません.キーボードには5行のキーがあります.
    次に、キーボードの定義を開始し、res/xml/qwerty.xmlファイルを作成します.その内容は次のとおりです.
    <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="10%p" android:horizontalGap="0px" android:verticalGap="0px" android:keyHeight="60dp" >
        <Row>
            <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
            <Key android:codes="50" android:keyLabel="2"/>
            <Key android:codes="51" android:keyLabel="3"/>
            <Key android:codes="52" android:keyLabel="4"/>
            <Key android:codes="53" android:keyLabel="5"/>
            <Key android:codes="54" android:keyLabel="6"/>
            <Key android:codes="55" android:keyLabel="7"/>
            <Key android:codes="56" android:keyLabel="8"/>
            <Key android:codes="57" android:keyLabel="9"/>
            <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
        </Row>
        <Row>
            <Key android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>
            <Key android:codes="119" android:keyLabel="w"/>
            <Key android:codes="101" android:keyLabel="e"/>
            <Key android:codes="114" android:keyLabel="r"/>
            <Key android:codes="116" android:keyLabel="t"/>
            <Key android:codes="121" android:keyLabel="y"/>
            <Key android:codes="117" android:keyLabel="u"/>
            <Key android:codes="105" android:keyLabel="i"/>
            <Key android:codes="111" android:keyLabel="o"/>
            <Key android:codes="112" android:keyLabel="p" android:keyEdgeFlags="right"/>
        </Row>
        <Row>
            <Key android:codes="97" android:keyLabel="a" android:keyEdgeFlags="left"/>
            <Key android:codes="115" android:keyLabel="s"/>
            <Key android:codes="100" android:keyLabel="d"/>
            <Key android:codes="102" android:keyLabel="f"/>
            <Key android:codes="103" android:keyLabel="g"/>
            <Key android:codes="104" android:keyLabel="h"/>
            <Key android:codes="106" android:keyLabel="j"/>
            <Key android:codes="107" android:keyLabel="k"/>
            <Key android:codes="108" android:keyLabel="l"/>
            <Key android:codes="35,64" android:keyLabel="\# \@" android:keyEdgeFlags="right"/>
        </Row>
        <Row>
            <Key android:codes="-1" android:keyLabel="CAPS" android:keyEdgeFlags="left"/>
            <Key android:codes="122" android:keyLabel="z"/>
            <Key android:codes="120" android:keyLabel="x"/>
            <Key android:codes="99" android:keyLabel="c"/>
            <Key android:codes="118" android:keyLabel="v"/>
            <Key android:codes="98" android:keyLabel="b"/>
            <Key android:codes="110" android:keyLabel="n"/>
            <Key android:codes="109" android:keyLabel="m"/>
            <Key android:codes="46" android:keyLabel="."/>
            <Key android:codes="63,33,58" android:keyLabel="\? ! :" android:keyEdgeFlags="right"/>
        </Row>
        <Row android:rowEdgeFlags="bottom">
            <Key android:codes="44" android:keyLabel="," android:keyWidth="10%p" android:keyEdgeFlags="left"/>
            <Key android:codes="47" android:keyLabel="/" android:keyWidth="10%p" />
            <Key android:codes="32" android:keyLabel="SPACE" android:keyWidth="40%p" android:isRepeatable="true"/>
            <Key android:codes="-5" android:keyLabel="DEL" android:keyWidth="20%p" android:isRepeatable="true"/>
            <Key android:codes="-4" android:keyLabel="DONE" android:keyWidth="20%p" android:keyEdgeFlags="right"/>
        </Row>
    </Keyboard>

    いくつかのキーのcodeは負数であり、負数はKeyboardで予め定義された定数に等しく、例えば-5Keyboard.KEYCODE_DELETEに等しいことに気づいたかもしれません.Serviceクラスの作成
    新しいjavaクラスを作成し、SimpleIMEとしてコマンドします.JAvaは、このクラスがInputMethodServiceクラスから継承され、OnKeyboardActionListenerインタフェースを実現するために、OnKeyboardActionListenerインタフェースの方法は、キーボード上のキーがクリックまたは押下されたときに呼び出される.SimpleIMEクラスには3つのメンバー変数があります.
  • KeyboardView layoutで定義したview
  • KeyboardKeyboardViewのインスタンス
  • に割り当てる.
  • booleanタイプの値は、caps lockが使用可能かどうかを表す
  • である.
    次に、OnKeyboardActionListenerの方法を実装し、SimpleIMEのコードは以下のようになる.
    public class SimpleIME extends InputMethodService implements OnKeyboardActionListener{
    
        private KeyboardView kv;
        private Keyboard keyboard;
    
        private boolean caps = false;
    
        @Override
        public void onKey(int primaryCode, int[] keyCodes) {
    
        }
    
        @Override
        public void onPress(int primaryCode) {
        }
    
        @Override
        public void onRelease(int primaryCode) {
        }
    
        @Override
        public void onText(CharSequence text) {
        }
    
        @Override
        public void swipeDown() {
        }
    
        @Override
        public void swipeLeft() {
        }
    
        @Override
        public void swipeRight() {
        }
    
        @Override
        public void swipeUp() {
        }
    }

    キーボードが作成されるとonCreateInputViewメソッドが呼び出され、このメソッドでは3つのメンバー変数を初期化し、onCreateInputViewのコードは以下のようになります.
    @Override
    public View onCreateInputView() {
        kv = (KeyboardView)getLayoutInflater().inflate(R.layout.keyboard, null);
        keyboard = new Keyboard(this, R.xml.qwerty);
        kv.setKeyboard(keyboard);
        kv.setOnKeyboardActionListener(this);
        return kv;
    }

    次に、あるキーを押すと音がします.AudioManagerを使ってこの音を再生します.Android SDKはキーボードの音響効果を提供しています.playClickで使用しています.
    private void playClick(int keyCode){
        AudioManager am = (AudioManager)getSystemService(AUDIO_SERVICE);
        switch(keyCode){
        case 32:
            am.playSoundEffect(AudioManager.FX_KEYPRESS_SPACEBAR);
            break;
        case Keyboard.KEYCODE_DONE:
        case 10:
            am.playSoundEffect(AudioManager.FX_KEYPRESS_RETURN);
            break;
        case Keyboard.KEYCODE_DELETE:
            am.playSoundEffect(AudioManager.FX_KEYPRESS_DELETE);
            break;
        default:
            am.playSoundEffect(AudioManager.FX_KEYPRESS_STANDARD);
        }
    }

    最後に、onKeyメソッドを編集して、私たちの入力メソッドが他のアプリケーションの入力ボックスとインタラクティブになるようにします.getCurrentInputConnectionメソッドは、私たちの入力メソッドと他のアプリケーションとの接続を取得することができます.接続を取得すると、以下の方法を使用することができます.
  • commitTextは、編集ボックスに1つ以上の文字
  • を追加することができる.
  • deleteSurroundingText編集ボックスの複数の文字
  • を削除できます.
  • sendKeyEventは、イベントを他のアプリケーション、例えばKEYCODE_ENTER
  • に送信することができる.
    ユーザがキーボード上のキーを押すとonKeyが呼び出され、このキーのunicode値が送信され、この値に基づいてキーボードは以下のアニメーションを実行することができる.
  • codeがKEYCODE_DELETEの場合、deleteSurroundingTextメソッドを使用してカーソルの左側の文字を削除します.
  • codeがKEYCODE_DONEである場合、KEYCODE_ENTERイベントが送信される.
  • codeがKEYCODE_SHIFTである場合、booleanタイプのcapsの値が変更され、setShiftedメソッドを使用してキーボードの (shift state)が変更され、ステータスが変更されるとキーボードが再描画される必要があるため、キーのlabelが更新され、invalidateAllKeysメソッドはすべてのキーを再描画するために使用される.
  • 他のすべてのcodesについては、uncodeを文字に変換して入力ボックスに送信するだけです.このcodeがアルファベット表のアルファベットを表し、caps変数がtrueであれば、アルファベットを大文字に変換する必要があります.onKeyのコードを修正し、
  • @Override
    public void onKey(int primaryCode, int[] keyCodes) {
        InputConnection ic = getCurrentInputConnection();
        playClick(primaryCode);
        switch(primaryCode){
        case Keyboard.KEYCODE_DELETE :
            ic.deleteSurroundingText(1, 0);
            break;
        case Keyboard.KEYCODE_SHIFT:
            caps = !caps;
            keyboard.setShifted(caps);
            kv.invalidateAllKeys();
            break;
        case Keyboard.KEYCODE_DONE:
            ic.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER));
            break;
        default:
            char code = (char)primaryCode;
            if(Character.isLetter(code) && caps){
                code = Character.toUpperCase(code);
            }
            ic.commitText(String.valueOf(code),1);
        }
    }

    キーボードのテスト
    私たちのキーボードは今テストすることができて、私たちのプログラムをandroidデバイスに実行して、このアプリケーションはactivityがなくて、これは私たちのアプリケーションがlauncherの中に現れないことを意味して、それを使うには、私たちは設定の中でそれをアクティブにする必要があります
    Android创建自定义键盘_第2张图片
    Simple IMEをアクティブにすると、入力ボックスのあるアプリケーション(メッセージなど)を開き、入力ボックスをクリックすると、通知欄に入力法の画像が表示されます.デバイスに依存して、アイコンをクリックしたり、通知欄を引いたりして入力法としてSimple IMEを選択することができます.新しい入力法で内容を入力することができます.
    Android创建自定义键盘_第3张图片