47

入力方法に関する developer.android.comの例に従い、 SoftKeyboardサンプル アプリケーションで遊んでみました。これらを合わせると、単純なキーボードの作成に関する十分な情報が得られます。

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

ここに画像の説明を入力

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

ここに画像の説明を入力

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

これまでのところ、これがどのように達成されるかについての単一の情報源を見つけていません。うまくいけば、誰かが私に有利なスタートを切ることができるでしょう。それまでは、組み込みキーボードのソースコードをたどって、リバースエンジニアリングできるかどうかを確認しますそれ。

編集: developer.android.comの LatinIME キーボードへのリンクがの写真にリンクしていない場合に役立ちます:) LatinIME.javaの実際のソースコード。

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

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

編集3:

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

ここに画像の説明を入力

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

編集 4:トピックから少しずれているため、重要なプレビューの質問をここに移動しました。

SoftKeyboard キー プレビュー ウィンドウを無効にするにはどうすればよいですか?

4

7 に答える 7

57

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

ポップアップ キーボードが必要なキーごとに、popupCharacterspopupKeyboardを定義する必要があります。

/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 ソース コードを完全に書き直すことなく) キー プレビューを表示するために一緒にノックすることができた唯一の解決策は次のとおりです。

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

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

これが生成されます:

ここに画像の説明を入力

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

于 2011-10-13T16:07:32.330 に答える
15

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

  • 便利な/派手な機能を使用するには、通常KeyboardView、描画コードの大部分を拡張して基本的に記述する必要があります。残念ながら、ほとんどすべてが非公開であるため、いくつかの主要なメソッドをオーバーライドしてこれを行うことはできません。あなたは見てみたいと思うかもしれません(そしていくつかのコードを以下から借ります:
    • (base)/core/java/android/inputmethodservice/KeyboardView.java(アンドロイドコアコードレポ)
    • (apps)/other/LatinIME/LatinKeyboardView.java(Android コア アプリ リポジトリ)

android.kernel.org の羊は、レポがクラッカーのために閉鎖されていることを伝えるためにそこにあることに注意してください。

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

今あなたができることについて:

  • キーの画像を提供することで、この問題を回避できます。これには 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 キーコードのリストを使用します。

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

シングルタップの場合は 97=' '、ダブルタップのa場合は 224=' '、トリプルタップの場合は 230=' ' が生成されます。àæ

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

ダブルタップすると、基本的にa最初に「 」が送信され、次に 2 回目のタップで「 」が送信されることに注意してくださいà。一部のアプリは、これを好まないでしょう。

于 2011-10-14T09:01:38.373 に答える
12

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

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == '1') {
        getOnKeyboardActionListener().onKey('!', null);
        return true;
    }
}
于 2013-09-21T12:54:46.787 に答える
8

キーの上にテキストを表示したい場合は、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
            {}
        }
    }
}
于 2016-03-12T05:55:17.107 に答える
6

ビュー領域の外側をタップしてポップアップキーボードを閉じようとしている人のために、クラス拡張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 ...
}
于 2016-09-24T10:27:23.813 に答える