android - 如何制作适用于 Android 的曲面屏幕键盘

标签 android keyboard

我想为 Android 制作一个弯曲的屏幕键盘。我检查了软键盘,以及谷歌代码上的各种其他屏幕键盘。我发现没有一个键盘形状不是矩形。理想情况下,我想创建一个键盘,该键盘由分布在屏幕两侧的两个半圆上的按键组成(即,想象一下将平板电脑放在两侧并能够用拇指敲击按键)。

在我检查过的代码中,屏幕键盘被创建为 View (通常扩展 KeyboardView)并显示为屏幕底部的连续条。作为我的目标的近似值,我试图改变我在谷歌代码(dotdash-keyboard-android)上找到的代码,只在左下角绘制它的键,并使右下角保持透明。我已经能够覆盖 onMeasure 以影响 View 的尺寸(见下文),但这似乎只会改变键的位置而不是容器的位置。换句话说,屏幕底部仍然有一个黑条。

//Located within KeyboardView
@Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    this.setMeasuredDimension(200, 200);
}

我想做的甚至可能吗?有更正确的术语吗?有没有可以用作示例的项目?

我还尝试使用 this.setLayoutParams 设置 View 的尺寸——但是,这些调用似乎没有效果。我也尝试使用 this.getParent 访问父 View (如果甚至存在的话)并更改它的尺寸,但这种方法不起作用(或者,我只是做错了)。任何帮助将非常感激。

谢谢

更新:12/21/2012 - 我想我需要重写父类的 onDraw 方法。望 here ,看起来 KeyboardView 的 onDraw 方法使用以下代码绘制到等于屏幕大小的 Canvas :
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 并在 Canvas 上绘制我想要的任何东西。

更新:2012 年 12 月 21 日-我已经覆盖了 onDraw,现在很明显,keyboardView 是我将其设置为 (200x200) 的尺寸。使用 Hierarchyview,我可以看到键盘 View 位于 ID 为 InputArea 的框架布局内。所以,填满整个宽度的单杠就是这个framelayout。但是,我不是在创造它——它来自哪里,我怎样才能改变它的尺寸?

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

更新:2012 年 12 月 23 日 - 进展。我已经弄清楚如何从键盘 IME 显示弹出窗口。下一步是弄清楚如何使弹出窗口有点圆/有机。这是我完成的屏幕截图,然后是源代码。
Emulator screenshot of keyboard

资源。以下方法在服务 IME 类中,由子(服务) View 的 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();
    }
}

最佳答案

你在这里似乎走在了正确的轨道上。正如您所指出的,大多数 Activity 都会缩小其 View 以为键盘窗口提供空间,因此如果您希望调用 Activity 填满屏幕,您需要使用辅助窗口,例如 PopupWindow。您可以将主窗口的尺寸设置为 0x0。

你试过调用popUpLeft.setBackgroundDrawable(null)吗?/popUpRight.setBackgroundDrawable(null) ?这应该删除半透明背景并仅显示您在顶部绘制的任何内容。

关于android - 如何制作适用于 Android 的曲面屏幕键盘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13984378/

相关文章:

iphone - 如何将焦点设置到 iPhone 中的下一个 uitextfield?

c++ - 防止无形式的应用程序因键盘 Hook 而关闭

winapi - 键盘的 SendInput() - 只有小写

java - GCM 连接错误

android - Android应用程序的命名约定?

android - 通过 IPC 将对象列表从服务传递到 Activity 时,Parcelable 项目消失

android - 在Android中导入一个类并实现一个功能

java - 如何查找OutOfMemoryError的原因?

android - 如何在回车键上隐藏键盘

用于显示哪些键盘输入输出的 Linux、Unix 或 OS X 工具?