如何为Android制作弧形屏幕键盘

如何为Android制作弧形屏幕键盘,android,keyboard,Android,Keyboard,我想为Android制作一个弧形屏幕键盘。我已经检查了谷歌代码上的软键盘和其他各种屏幕键盘。我所发现的键盘形状都不是矩形。理想情况下,我想创建一个键盘,它由分布在屏幕两侧的两个半圆上的键组成(例如,想象一下,握住平板电脑的两侧并能够用拇指敲击键) 在我所研究的代码中,屏幕上的键盘被创建为视图(通常扩展键盘视图),并在屏幕底部显示为一个连续的条。为了接近我的目标,我尝试改变我在谷歌代码(dotdash键盘android)上找到的代码,只在左下角画出它的键,让右下角透明。我已经能够覆盖onMeasu

我想为Android制作一个弧形屏幕键盘。我已经检查了谷歌代码上的软键盘和其他各种屏幕键盘。我所发现的键盘形状都不是矩形。理想情况下,我想创建一个键盘,它由分布在屏幕两侧的两个半圆上的键组成(例如,想象一下,握住平板电脑的两侧并能够用拇指敲击键)

在我所研究的代码中,屏幕上的键盘被创建为视图(通常扩展键盘视图),并在屏幕底部显示为一个连续的条。为了接近我的目标,我尝试改变我在谷歌代码(dotdash键盘android)上找到的代码,只在左下角画出它的键,让右下角透明。我已经能够覆盖onMeasure来影响视图的尺寸(见下文),但这似乎只是改变了关键点的位置,而不是容器的位置。换句话说,屏幕底部仍然有一个黑色条

//Located within KeyboardView
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    this.setMeasuredDimension(200, 200);
}
我想做的事情可能吗?有没有更正确的说法?有没有我可以作为例子的项目

我还尝试使用this.setLayoutParams设置视图的维度——但是,这些调用似乎没有效果。我还尝试使用this.getParent访问父视图(如果存在)并更改其维度,但这种方法不起作用(或者,我只是做错了)。任何帮助都将不胜感激

多谢各位

更新:12/21/2012-我想我需要重写父类的onDraw方法。看起来,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);
我想我可以在画布上画我想要的任何东西

更新:2012年12月21日-我已覆盖onDraw,现在很清楚,键盘视图是我将其设置为(200x200)的尺寸。使用Hierarchyview,我可以看到keyboardview位于id为InputArea的framelayout中。因此,填充整个宽度的水平条就是这个framelayout。但是,我不是在创造它——它是从哪里来的,我怎样才能改变它的维度

更新:2012年12月22日-经过更多测试,键盘视图的行为(尺寸)似乎部分取决于调用它的活动。在浏览器中,我得到了我一直在描述的行为:浏览器窗口的高度收缩,以容纳屏幕底部的一个横条,该横条可以容纳键盘,即使键盘的宽度小于屏幕的宽度。在calendar应用程序中,键盘大小显示为我设置的大小(在左下角显示为一个正方形),其下方的日历显示不变。因此,使用这种方法的大多数应用程序似乎不可能达到我的目标。另一种方法可能是让IME服务创建一个弹出窗口或对话框。一个问题是PopupWindow需要附加一个父视图或锚点,我认为不可能从IME服务中找到最顶层的视图。也许我可以在当前活动上创建一个透明视图,并将弹出窗口放在上面

更新:2012年12月23日-进展。我已经知道如何显示键盘输入法中的弹出窗口。下一步是找出如何使弹出窗口有点圆/有机。这是我完成的一个截图,后面是来源。

来源。以下方法位于服务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();
    }
}

你似乎在正确的轨道上。正如您所注意到的,大多数活动都会缩小其视图以为键盘窗口提供空间,因此如果您希望调用活动填充屏幕,则需要使用辅助窗口,如弹出窗口。您可以将主窗口的尺寸设置为0x0


您是否尝试过调用
popUpLeft.setBackgroundDrawable(null)
/
popuplight.setBackgroundDrawable(null)
?这将删除半透明背景,并仅显示您在顶部绘制的任何内容。

查看此链接。有趣的问题-将跟随它寻找可能的答案。。。。很遗憾,我没有什么可以补充的来帮助你。