Android用の曲面オンスクリーンキーボードを作りたいです。私はソフトキーボードと、Googleコードの他のさまざまなオンスクリーンキーボードを調べました。私が見つけたものには、長方形以外のキーボード形状が含まれていません。理想的には、画面の反対側にある 2 つの半円に配置されたキーで構成されるキーボードを作成したいと考えています (つまり、タブレットの両側を持ち、親指でキーを押すことができると想像してください)。
私が調べたコードのうち、オンスクリーン キーボードはビュー (通常は KeyboardView を拡張) として作成され、画面の下部に連続するバーとして表示されます。私の目標の近似値として、Google コード (dotdash-keyboard-android) で見つけたコードを変更して、キーを左下隅にのみ描画し、右下隅を透明のままにしようとしました。onMeasure をオーバーライドしてビューの寸法に影響を与えることができました (以下を参照) が、これはキーの位置を変更するだけで、コンテナの位置は変更しないようです。つまり、画面の下部を埋める黒いバーがまだあります。
//Located within KeyboardView
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
this.setMeasuredDimension(200, 200);
}
私がやりたいことは可能ですか?これについてもっと正しい用語はありますか?例として使用できるプロジェクトはありますか?
this.setLayoutParams を使用してビューのサイズを設定しようとしましたが、これらの呼び出しは効果がないようです。また、 this.getParent を使用して親ビューにアクセスし (存在する場合)、そのサイズを変更しようとしましたが、このアプローチは機能しません (または、間違っているだけです)。どんな助けでも大歓迎です。
ありがとうございました
更新: 2012 年 12 月 21 日 - 親クラスの onDraw メソッドをオーバーライドする必要があると思います。hereを見ると、次のコードを使用して、KeyboardView の onDraw メソッドが画面のサイズに等しいキャンバスに描画しているように見えます。
final int width = Math.max(1, getWidth());
final int height = Math.max(1, getHeight());
mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBuffer);
onDraw をオーバーライドして、キャンバスに好きなものを描画できると思います。
更新: 2012 年 12 月 21 日 - onDraw をオーバーライドしましたが、keyboardView が (200x200) に設定しているサイズであることは明らかです。Hierarchyview を使用すると、id が InputArea のフレームレイアウト内にキーボードビューがあることがわかります。というわけで、横幅いっぱいの横棒がこのフレームレイアウトです。しかし、私はそれを作成していません。それはどこから来て、どのように寸法を変更できますか?
更新: 2012 年 12 月 22 日 - さらにテストした結果、keyboardview の動作 (寸法) は、それを呼び出すアクティビティによって部分的に決定されるようです。ブラウザーでは、私が説明してきた動作が得られます。キーボードの幅がキーボードの幅よりも小さい場合でも、ブラウザー ウィンドウの高さは、キーボードを保持する画面の下部にあるバーに合わせて縮小されます。画面。カレンダー アプリでは、設定したとおりのキーボード サイズが (左下隅の四角として) 表示され、その下にカレンダーが変更されずに表示されます。したがって、このアプローチを使用するほとんどのアプリで私の目標を達成することは不可能に思えます。別の方法として、IME サービスに popupwindow またはダイアログを作成させることもできます。問題の 1 つは、popupwindows にはアタッチする親ビューまたはアンカーが必要であり、私はそうは思わないことです。IME サービスから最上位のビューを見つけることができます。おそらく、現在のアクティビティの透明なビューを作成し、その上にポップアップを配置できますか?
更新: 2012 年 12 月 23 日 - 進行状況。キーボード IME からポップアップを表示する方法を理解しました。次のステップは、ポップアップを少し丸く/有機的にする方法を見つけることです。これは、私が達成したことのスクリーンショットとそれに続くソースです。
ソース。次のメソッドはサービス IME クラスにあり、(サービスの) 子ビューの onMeasure メソッドによって呼び出されるため、キーボードが描画されると同時にポップアップが開きます。キーボードの寸法を 1x1 に設定したので、表示されません。ログ ステートメントは、ポップアップの配置方法を理解するのに役立ちます。
public void initiatePopupWindow()
{
try {
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
//display.getSize(p);
Log.i("dotdashkeyboard","initiatePopupWindow (from IME service)");
LayoutInflater inflater = (LayoutInflater) this.getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layoutLeft = inflater.inflate(R.layout.popup_layout_left,null);
View layoutRight = inflater.inflate(R.layout.popup_layout_right, null);
// create a 300px width and 470px height PopupWindow
int popupHeight = 300;
int popupWidth = 200;
if (popUpLeft == null) popUpLeft = new PopupWindow(layoutLeft, popupWidth, popupHeight, false);
if (popUpRight == null) popUpRight = new PopupWindow(layoutRight, popupWidth, popupHeight, false);
int ypos = 0;
int xposRight = 0;
if (display.getRotation() == Surface.ROTATION_0) {
ypos = -(dm.heightPixels / 2 + popupHeight/2);
xposRight = (dm.widthPixels - popupWidth);
Log.i("dotdashkeyboard","test rotation=normal");
} else if (display.getRotation() == Surface.ROTATION_90) {
ypos = -(dm.heightPixels / 2 + popupHeight/2)/2;
xposRight = (dm.widthPixels - popupWidth)*2-popupWidth;
Log.i("dotdashkeyboard","test rotation=90-degrees");
} else {
Log.i("dotdashkeyboard","test rotation=unknown=" + display.getRotation());
}
popUpLeft.showAtLocation(inputView, Gravity.NO_GRAVITY, 0, ypos);
popUpRight.showAtLocation(inputView, Gravity.NO_GRAVITY, xposRight, ypos);
Log.i("dotdashkeyboard","test created popup at ypos="+ypos + " xposRight=" + xposRight);
Log.i("dotdashkeyboard","test screenWidth=" + dm.widthPixels + " screenHeight=" + dm.heightPixels);
Button cancelButton = (Button) layoutLeft.findViewById(R.id.popup_cancel_button);
//cancelButton.setOnClickListener(inputView.cancel_button_click_listener);
cancelButton.setOnClickListener(cancel_button_click_listener);
} catch (Exception e) {
e.printStackTrace();
}
}