创建每个键具有多个/交替字符的软键盘

发布于 2024-12-09 18:38:03 字数 2153 浏览 0 评论 0 原文

我已按照 developer.android.com 上有关 输入法 并使用 SoftKeyboard 示例应用程序。这些共同提供了有关创建简单键盘的足够信息。

我在 API 中看不到的是标准键盘(LatinIME 键盘)上提供的每个键创建备用/多个字符的能力。

在此处输入图像描述

上面的图像是长按“a”键的结果。当您长按某个键时,可以使用替代字符填充弹出窗口。

在此处输入图像描述

还可以在某些按键上给出弹出提示,提示用户按住键以获得弹出菜单。

到目前为止,我还没有找到关于如何实现这一点的单一信息来源,希望有人能够给我一个良好的开端,在那之前我将跟踪内置键盘的源代码,看看我是否可以进行逆向工程它。

编辑:如果 developer.android.com 链接到 LatinIME 键盘会有帮助没有链接到羊的图片:) LatinIME.java

编辑2:更多的是作为参考,我相信这是通常的长按操作的顺序,以便在 KeyboardView.java

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

编辑3:

我仍然还没弄清楚 - 如何向按键添加标签建议?答案表明它没有内置到 API 中,而且实际上我还没有找到执行此操作的代码。但是 2.3.4 (API 10) 上的键盘显示正在实现此功能:

在此处输入图像描述

非常愿意弄清楚它是如何做到这一点的,但它不在我可以看到的 onDraw() 方法中的任何地方 - 这让我相信它是在 KeyboardView 元素之外编写的。然而,我找不到用于在内置键盘上显示 KeyboardView 元素的 layout 文件 - 如果有人知道在哪里可以找到这个文件,也许这会给我需要的线索。

编辑4:将按键预览问题移至此处,因为它有点偏离主题:

如何禁用软键盘按键预览窗口?

I've followed the examples on developer.android.com regarding Input Methods and played with the SoftKeyboard sample application. These together give more than enough information regarding the creation of simple keyboard.

What I can't see in the API is the ability to create alternate / multiple characters per key which is available on the standard Keyboard (LatinIME Keyboard).

enter image description here

The above image is the result of a long press on the "a" key. When you long press a key it's possible to populate a popup with alternate characters.

enter image description here

It is also possible to give a popup hint on some keys which will prompt the user to press and hold a key in order to get the popup menu.

So far I haven't found a single source of information on how this is achieved, hopefully someone will be able to give me a head start, until then I'll follow the source code of the inbuilt keyboard and see if I can reverse engineer it.

Edit: Would help if developer.android.com 's link to the LatinIME Keyboard didn't link to a picture of a Sheep :) Actual source code for LatinIME.java.

Edit 2: More as a reference than anything else, this is the sequence I believe a usual longPress action goes through in order to show the popup keyboard in KeyboardView.java:

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

Edit 3:

I still haven't figured this out - How do you add label suggestions to keys? An answer suggests it isn't built into the API and indeed I haven't found the codeto do this. However the Keyboard on 2.3.4 (API 10) shows this functionality being implemented:

enter image description here

Would very much like to figure out how IT does it but it isn't anywhere in the onDraw() method that I can see - which makes me believe it's being written outside of the KeyboardView element. I can't however find the layout file used to display the KeyboardView element on the inbuilt keyboard - If anyone knows where to find this perhaps that will give me the clue I need.

Edit 4: Moved key Preview question here as it's slightly off topic:

How do you disable the SoftKeyboard key preview window?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

佞臣 2024-12-16 18:38:03

实现备用键弹出:

对于您希望有弹出键盘的每个键,您应该定义popupCharacterspopupKeyboard

/res/xml/[ Keyboard].xml

<Key android:keyLabel="("
    android:popupKeyboard="@xml/keyboard_popup_template"
    android:popupCharacters="[{<" />

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 乘以行数来指定。在此标记内,我简单地创建了一个 LinearLayout 来保存行,然后为每行创建一个 LinearLayout,其中包含一个 TextView,其权重等于为每个 指定的 %p 值:

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

会产生这样的结果:

在此处输入图像描述

在我设法以相同的方式实现此操作之前,我不会感到高兴就像系统键盘一样!

Implementing alternate key popup:

For each key you wish to have a popup keyboard you should define popupCharacters and popupKeyboard:

/res/xml/[Keyboard].xml

<Key android:keyLabel="("
    android:popupKeyboard="@xml/keyboard_popup_template"
    android:popupCharacters="[{<" />

The popupKeyboard is an XML representation of the keyboard used in the popup containing the alternate keys:

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

Styling the alternate key popup:

If you want to change the layout/style of the popup (which defaults to @android:layout/ keyboard_popup_keyboard.xml) you can specify a android:popupLayout attribute which points to a layout file:

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

Implementing Key Preview Overlay:

The only solution I've been able to knock together to show key previews (Without entirely rewriting the KeyboardView source code) is below:

Wrapping the <KeyboardView> tag with a <FrameLayout> with a height specified by multiplying the keyHeight by the amount of rows. Inside this tag I've simply created a LinearLayout to hold rows, then a LinearLayout for each row containing a TextView with a weight equal to the %p value specified for each <Key>:

<TextView android:text="!" style="@style/Custom.Widget.KeyboardKeyOverlay"  android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="10"/>

And styled:

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

Which produces this:

enter image description here

I won't be happy until I've managed to implement this in the same way as the System Keyboard does!

假情假意假温柔 2024-12-16 18:38:03

从我自己编写软键盘的尝试来看,我发现:

  • Nice/bling 功能通常要求您扩展 KeyboardView 并基本上编写大部分绘图代码。不幸的是,您无法通过重写某些关键方法来做到这一点,因为几乎所有内容都是私有的。您可能想看一下(并从以下位置借用一些代码:
    • (base)/core/java/android/inputmethodservice/KeyboardView.java(android 核心代码仓库)
    • (apps)/other/LatinIME/LatinKeyboardView.java(Android 核心应用程序存储库)

请注意,android.kernel.org 上的绵羊在那里告诉您,由于破解者,该存储库已关闭,但其他地方有代码的镜像(不幸的是丢失了链接)

  • 基础 KeyboardView 没有支持阴影键提示,您必须编写自己的 KeyboardView 才能有机会重写 onDraw() 方法。

现在,您可以做什么:

  • 您可以通过提供按键图片来解决此问题:使用 xml

  • 您可以使用长按时出现的弹出键盘(并配置其外观)。

声明键盘模板 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 键码的列表

将生成 97='a' 表示单击,224='à' 表示双击,230='æ' 表示三次点击。

在 Android 源代码中,考虑双击的持续时间设置为 800ms。不幸的是它是硬编码的(我觉得有点高)。

请注意,双击时,它基本上首先发送“a”,然后在第二次点击时发送“à”。有些应用程序不会喜欢这样。

Judging from my own attempt at coding a softkeyboard I found out that:

  • Nice/bling features usually requires that you extend KeyboardView and basically write large parts of the drawing code. Unfortunately you cannot do this by overriding some key methods since almost everything is private. You might want to take a look (and borrow some code from:
    • (base)/core/java/android/inputmethodservice/KeyboardView.java (android core code repo)
    • (apps)/other/LatinIME/LatinKeyboardView.java (android core apps repo)

Note that the sheep on android.kernel.org is there to tell you that the repo is closed due to crackers but there are mirrors of the code elsewhere (lost the links unfortunately)

  • The base KeyboardView has no support for shadowed key hints, you must code your own KeyboardView to get a chance to override the onDraw() method.

Now on what you can do:

  • You can workaround this issue by providing pictures for the keys: use xml <Key ... android:keyIcon="@drawable/this_key_icon_file /> for this. Unfortunately, you'll most certainly have poor results for letters with this method (resolution issues).

  • You can use (and configure appearance of) popup keyboard that appears on long press.

Declare a keyboard template 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>

Declare string values containing the keys you want on this keyboard res/values/strings.xml:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string name="alternates_for_a">àáâãäåæ</string>
</ressources>

Then, use both in your keyboard layout definition:

<Key android:codes="97" android:keyLabel="a"  
    android:popupKeyboard="@xml/kbd_popup_template"
    android:popupCharacters="@string/alternates_for_a" />
  • You can also use double-tap, triple-tap, ... feature to generate alternates for the key you're tapping. To do so, simply use a list for the android keycodes:

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

will produce 97='a' for single tap, 224='à' for double-tap and 230='æ' for triple-tap.

The duration to consider double-tapping is set to 800ms in android source code. It's unfortunately hardcoded (and a bit high, I feel).

Be aware that, when double-tapping, it basically sends an 'a' first, then, on the second tap it sends 'à'. Some apps, will not like this.

[旋木] 2024-12-16 18:38:03

当我们只有一个弹出字符时,带有关闭按钮的弹出键盘很烦人。
更简单的方法是像这样重写 KeyboardView 类的 onLongPress 方法。

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == '1') {
        getOnKeyboardActionListener().onKey('!', null);
        return true;
    }
}

That popup keyboard with the close button is annoying when we have only one popup character.
Simpler way is to override the onLongPress method of KeyboardView class like this.

@Override
protected boolean onLongPress(Key key) {
    if (key.codes[0] == '1') {
        getOnKeyboardActionListener().onKey('!', null);
        return true;
    }
}
故人如初 2024-12-16 18:38:03

如果您想在按键顶部显示文本,可以在类中覆盖 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
            {}
        }
    }
}

If you want to have a text on top of your key, you can do it in onDraw() method in your class that overrides KeyboardView

 @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
            {}
        }
    }
}
身边 2024-12-16 18:38:03

对于任何试图通过点击视图区域外部来关闭弹出键盘的人,我很幸运在扩展 InputMethodService< 的类内的 KeyboardView 上放置了 TouchListener /代码>

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

For anyone trying to dismiss the popup keyboard by tapping outside its view area, I've had some luck putting a TouchListener on the KeyboardView inside the class extending InputMethodService

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 ...
}
飞烟轻若梦 2024-12-16 18:38:03

如果你想在你的按键上有一个文本,你可以在你的类中扩展KeyboardView的onDraw()方法中做到这一点我做了类似的事情也许这可以帮助某人

在此处输入图像描述

 @Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.d("LatinKeyboardView", "onDraw");

    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(30);
    paint.setColor(Color.LTGRAY);

    List<Key> keys = getKeyboard().getKeys();
    for (Key key : keys) {
        if (key.label != null) {
            switch (key.codes[0]) {

                //qQ
                case 81:
                case 113:
                case 1602:
                case 1618:
                    canvas.drawText(String.valueOf(1), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //wW
                case 87:
                case 119:
                case 1608:
                case 1572:
                    canvas.drawText(String.valueOf(2), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //eE
                case 69:
                case 101:
                case 1593:
                case 1617:
                    canvas.drawText(String.valueOf(3), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //rR
                case 82:
                case 114:
                case 1585:
                case 1681:
                    canvas.drawText(String.valueOf(4), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //tT
                case 84:
                case 116:
                case 1578:
                case 1657:
                    canvas.drawText(String.valueOf(5), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //yY
                case 89:
                case 121:
                case 1746:
                case 1552:
                    canvas.drawText(String.valueOf(6), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //uU
                case 85:
                case 117:
                case 1569:
                case 1574:
                    canvas.drawText(String.valueOf(7), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //iI
                case 73:
                case 105:
                case 1740:
                case 1648:
                    canvas.drawText(String.valueOf(8), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //oO
                case 79:
                case 111:
                case 1729:
                case 1731:
                    canvas.drawText(String.valueOf(9), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //pP
                case 80:
                case 112:
                case 1662:
                case 1615:
                    canvas.drawText(String.valueOf(0), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //aA
                case 65:
                case 97:
                case 1575:
                case 1570:
                    canvas.drawText("@", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //sS
                case 83:
                case 115:
                case 1587:
                case 1589:
                    canvas.drawText("#", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //dD
                case 68:
                case 100:
                case 1583:
                case 1672:
                    canvas.drawText("$", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //fF
                case 70:
                case 102:
                case 1601:
                case 1613:
                    canvas.drawText("%", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //gG
                case 71:
                case 103:
                case 1711:
                case 1594:
                    canvas.drawText("&", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //hH
                case 72:
                case 104:
                case 1726:
                case 1581:
                    canvas.drawText("-", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //jJ
                case 74:
                case 106:
                case 1580:
                case 1590:
                    canvas.drawText("+", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //kK
                case 75:
                case 107:
                case 1705:
                case 1582:
                    canvas.drawText("(", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //lL
                case 76:
                case 108:
                case 1604:
                case 1614:
                    canvas.drawText(")", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //zZ
                case 90:
                case 122:
                case 1586:
                case 1584:
                    canvas.drawText("*", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //xX
                case 88:
                case 120:
                case 1588:
                case 1679:
                    canvas.drawText("\"", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //cC
                case 67:
                case 99:
                case 1670:
                case 1579:
                    canvas.drawText("\'", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //vV
                case 86:
                case 118:
                case 1591:
                case 1592:
                    canvas.drawText(":", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //bB
                case 66:
                case 98:
                case 1576:
                case 1616:
                    canvas.drawText(";", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //nN
                case 78:
                case 110:
                case 1606:
                case 1722:
                    canvas.drawText("!", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //mM
                case 77:
                case 109:
                case 1605:
                case 1611:
                    canvas.drawText("?", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


            }

        }

    }
}

根据调整这些轴根据您的选择

int keyXAxis = 25;
int keyYAxis = 50;

if you want to have a text on top of your key, you can do it in onDraw() method in your class that extends KeyboardView i did something like this maybe this could help someone

enter image description here

 @Override
public void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Log.d("LatinKeyboardView", "onDraw");

    Paint paint = new Paint();
    paint.setTextAlign(Paint.Align.CENTER);
    paint.setTextSize(30);
    paint.setColor(Color.LTGRAY);

    List<Key> keys = getKeyboard().getKeys();
    for (Key key : keys) {
        if (key.label != null) {
            switch (key.codes[0]) {

                //qQ
                case 81:
                case 113:
                case 1602:
                case 1618:
                    canvas.drawText(String.valueOf(1), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //wW
                case 87:
                case 119:
                case 1608:
                case 1572:
                    canvas.drawText(String.valueOf(2), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //eE
                case 69:
                case 101:
                case 1593:
                case 1617:
                    canvas.drawText(String.valueOf(3), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //rR
                case 82:
                case 114:
                case 1585:
                case 1681:
                    canvas.drawText(String.valueOf(4), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //tT
                case 84:
                case 116:
                case 1578:
                case 1657:
                    canvas.drawText(String.valueOf(5), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //yY
                case 89:
                case 121:
                case 1746:
                case 1552:
                    canvas.drawText(String.valueOf(6), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //uU
                case 85:
                case 117:
                case 1569:
                case 1574:
                    canvas.drawText(String.valueOf(7), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //iI
                case 73:
                case 105:
                case 1740:
                case 1648:
                    canvas.drawText(String.valueOf(8), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //oO
                case 79:
                case 111:
                case 1729:
                case 1731:
                    canvas.drawText(String.valueOf(9), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //pP
                case 80:
                case 112:
                case 1662:
                case 1615:
                    canvas.drawText(String.valueOf(0), key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


                //aA
                case 65:
                case 97:
                case 1575:
                case 1570:
                    canvas.drawText("@", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //sS
                case 83:
                case 115:
                case 1587:
                case 1589:
                    canvas.drawText("#", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //dD
                case 68:
                case 100:
                case 1583:
                case 1672:
                    canvas.drawText("$", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //fF
                case 70:
                case 102:
                case 1601:
                case 1613:
                    canvas.drawText("%", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //gG
                case 71:
                case 103:
                case 1711:
                case 1594:
                    canvas.drawText("&", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //hH
                case 72:
                case 104:
                case 1726:
                case 1581:
                    canvas.drawText("-", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //jJ
                case 74:
                case 106:
                case 1580:
                case 1590:
                    canvas.drawText("+", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //kK
                case 75:
                case 107:
                case 1705:
                case 1582:
                    canvas.drawText("(", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //lL
                case 76:
                case 108:
                case 1604:
                case 1614:
                    canvas.drawText(")", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //zZ
                case 90:
                case 122:
                case 1586:
                case 1584:
                    canvas.drawText("*", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //xX
                case 88:
                case 120:
                case 1588:
                case 1679:
                    canvas.drawText("\"", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //cC
                case 67:
                case 99:
                case 1670:
                case 1579:
                    canvas.drawText("\'", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //vV
                case 86:
                case 118:
                case 1591:
                case 1592:
                    canvas.drawText(":", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //bB
                case 66:
                case 98:
                case 1576:
                case 1616:
                    canvas.drawText(";", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;

                //nN
                case 78:
                case 110:
                case 1606:
                case 1722:
                    canvas.drawText("!", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;
                //mM
                case 77:
                case 109:
                case 1605:
                case 1611:
                    canvas.drawText("?", key.x + (key.width - keyXAxis), key.y + keyYAxis, paint);
                    break;


            }

        }

    }
}

adjust these axis according to your choice

int keyXAxis = 25;
int keyYAxis = 50;
云醉月微眠 2024-12-16 18:38:03

根据这里的答案,我所做的是:

public class MyKeyboardView extends KeyboardView {
    private Keyboard.Key longPressedKey = null;

    public MyKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyKeyboardView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setTextAlign(Paint.Align.CENTER);
        paint.setTextSize(35);
        paint.setColor(Color.BLACK);
        //get all your keys and draw whatever you want
        List<Keyboard.Key> keys = getKeyboard().getKeys();
        for (Keyboard.Key key : keys) {
            if (key.popupCharacters != null && key.popupCharacters.length() > 0) {
                canvas.drawText(key.popupCharacters.toString(), key.x + (key.width / 2) + 10, key.y + 30, paint);
            }
        }
    }


    @Override
    protected boolean onLongPress(Keyboard.Key key) {
        if (key.popupCharacters != null && key.popupCharacters.length() > 0)
            longPressedKey = key;
        return super.onLongPress(key);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (longPressedKey != null) {
                // TODO: Try detecting what key the finger is above if there are many popupCharacters
                getOnKeyboardActionListener().onKey((longPressedKey.popupCharacters.charAt(0)), null);
                dismissPopupKeyboard();
                longPressedKey = null;
            }
        }
        return true; // Required for recieving subsequent events (ACTION_MOVE, ACTION_UP)
    }

    private void dismissPopupKeyboard() {
        // Because of KeyboardView.dismissPopupKeyboard() is private, we are doing this trick (KeyboardView.click() calls dismissPopupKeyboard()).
        // TODO: Make this like a normal human. We will need to create the popup on our own like the way the keyboard does it.
        onClick(new View(getContext()));
    }

使用KeyboardView将其更改为MyKeyboardView时,带有这个额外的参数 - android:popupLayout="@layout/keyboard_popup_keyboard"

这是keyboard_popup_keyboard.xml(重要所以不会有取消按钮)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >

    <android.inputmethodservice.KeyboardView
        android:id="@android:id/keyboardView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/popup_key_color"
        android:keyPreviewLayout="@layout/key_preview"
        android:keyPreviewOffset="0px"
        android:keyPreviewHeight="@dimen/key_preview_height"
        android:keyTextColor="@color/darkGray"
        android:keyBackground="@drawable/key_background_selector"
        android:shadowRadius="0.0"
        android:horizontalGap="0px"
        android:verticalGap="0px" />
</LinearLayout>

Base on the answers here, what I did was:

public class MyKeyboardView extends KeyboardView {
    private Keyboard.Key longPressedKey = null;

    public MyKeyboardView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyKeyboardView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }


    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        Paint paint = new Paint();
        paint.setTextAlign(Paint.Align.CENTER);
        paint.setTextSize(35);
        paint.setColor(Color.BLACK);
        //get all your keys and draw whatever you want
        List<Keyboard.Key> keys = getKeyboard().getKeys();
        for (Keyboard.Key key : keys) {
            if (key.popupCharacters != null && key.popupCharacters.length() > 0) {
                canvas.drawText(key.popupCharacters.toString(), key.x + (key.width / 2) + 10, key.y + 30, paint);
            }
        }
    }


    @Override
    protected boolean onLongPress(Keyboard.Key key) {
        if (key.popupCharacters != null && key.popupCharacters.length() > 0)
            longPressedKey = key;
        return super.onLongPress(key);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (longPressedKey != null) {
                // TODO: Try detecting what key the finger is above if there are many popupCharacters
                getOnKeyboardActionListener().onKey((longPressedKey.popupCharacters.charAt(0)), null);
                dismissPopupKeyboard();
                longPressedKey = null;
            }
        }
        return true; // Required for recieving subsequent events (ACTION_MOVE, ACTION_UP)
    }

    private void dismissPopupKeyboard() {
        // Because of KeyboardView.dismissPopupKeyboard() is private, we are doing this trick (KeyboardView.click() calls dismissPopupKeyboard()).
        // TODO: Make this like a normal human. We will need to create the popup on our own like the way the keyboard does it.
        onClick(new View(getContext()));
    }

and

When used KeyboardView changed it to MyKeyboardView, with this extra param - android:popupLayout="@layout/keyboard_popup_keyboard"

And this is keyboard_popup_keyboard.xml (important so there wont be a cancel button)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    >

    <android.inputmethodservice.KeyboardView
        android:id="@android:id/keyboardView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@color/popup_key_color"
        android:keyPreviewLayout="@layout/key_preview"
        android:keyPreviewOffset="0px"
        android:keyPreviewHeight="@dimen/key_preview_height"
        android:keyTextColor="@color/darkGray"
        android:keyBackground="@drawable/key_background_selector"
        android:shadowRadius="0.0"
        android:horizontalGap="0px"
        android:verticalGap="0px" />
</LinearLayout>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文