如何在 Android 中制作自定义键盘?

新手上路,请多包涵

我想制作一个自定义键盘。我不知道如何使用 XML 和 Java 来做到这一点。下图是我要制作的键盘模型。它只需要数字。

在此处输入图像描述

原文由 XX_brother 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
1 个回答

系统键盘

这个答案告诉我们如何制作一个可以在用户安装在他们手机上的任何应用程序中使用的自定义系统键盘。如果您想制作只在您自己的应用程序中使用的键盘, 请参阅我的其他答案

下面的示例将如下所示。您可以针对任何键盘布局修改它。

在此处输入图像描述

以下步骤展示了如何创建一个有效的自定义系统键盘。我尽可能地尝试删除任何不必要的代码。如果您需要其他功能,我在最后提供了指向更多帮助的链接。

1.开始一个新的Android项目

我将我的项目命名为“自定义键盘”。随心所欲地称呼它。这里没有什么特别的。我将只留下 MainActivity 和“Hello World!”布局原样。

2.添加布局文件

将以下两个文件添加到应用程序的 res/layout 文件夹:

  • 键盘视图.xml
  • key_preview.xml

键盘视图.xml

这个视图就像一个容器,可以容纳我们的键盘。在此示例中,只有一个键盘,但您可以添加其他键盘并将它们交换进出这个 KeyboardView

 <?xml version="1.0" encoding="utf-8"?>
<android.inputmethodservice.KeyboardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/keyboard_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:keyPreviewLayout="@layout/key_preview"
    android:layout_alignParentBottom="true">

</android.inputmethodservice.KeyboardView>

key_preview.xml

按键预览是当您按下键盘按键时弹出的布局。它只显示您按下的是哪个键(以防您的粗大手指盖住了它)。这不是多项选择弹出窗口。为此,您应该查看 Candidates 视图

 <?xml version="1.0" encoding="utf-8"?>
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:background="@android:color/white"
    android:textColor="@android:color/black"
    android:textSize="30sp">
</TextView>

3.添加支持的xml文件

在您的 res 文件夹中创建一个 xml 文件夹。 (右键单击 res 并选择 New > Directory 。)

然后向其中添加以下两个xml文件。 (右键单击 xml 文件夹并选择 New > XML resource file 。)

  • number_pad.xml
  • 方法.xml

number_pad.xml

这是它开始变得更有趣的地方。这 Keyboard 定义了 的布局。

 <?xml version="1.0" encoding="utf-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyWidth="20%p"
    android:horizontalGap="5dp"
    android:verticalGap="5dp"
    android:keyHeight="60dp">

    <Row>
        <Key android:codes="49" android:keyLabel="1" android:keyEdgeFlags="left"/>
        <Key android:codes="50" android:keyLabel="2"/>
        <Key android:codes="51" android:keyLabel="3"/>
        <Key android:codes="52" android:keyLabel="4"/>
        <Key android:codes="53" android:keyLabel="5" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="54" android:keyLabel="6" android:keyEdgeFlags="left"/>
        <Key android:codes="55" android:keyLabel="7"/>
        <Key android:codes="56" android:keyLabel="8"/>
        <Key android:codes="57" android:keyLabel="9"/>
        <Key android:codes="48" android:keyLabel="0" android:keyEdgeFlags="right"/>
    </Row>

    <Row>
        <Key android:codes="-5"
             android:keyLabel="DELETE"
             android:keyWidth="40%p"
             android:keyEdgeFlags="left"
             android:isRepeatable="true"/>
        <Key android:codes="10"
             android:keyLabel="ENTER"
             android:keyWidth="60%p"
             android:keyEdgeFlags="right"/>
    </Row>

</Keyboard>

以下是一些需要注意的事项:

  • keyWidth :这是每个键的默认宽度。 --- 20%p 意味着每个键应该占据父键宽度的 20%。不过,它可以被单独的键覆盖,正如您在第三行中看到的 Delete 和 Enter 键所发生的那样。
  • keyHeight :它在这里是硬编码的,但你可以使用类似 @dimen/key_height 的东西来为不同的屏幕尺寸动态设置它。
  • Gap :水平和垂直间隙表示键之间留出多少空间。即使你设置为 0px 也还是有一点差距。
  • codes :这可以是 Unicode 或自定义代码值,用于确定按下键时发生的情况或输入的内容。如果要输入更长的 Unicode 字符串,请参阅 keyOutputText
  • keyLabel :这是显示在按键上的文本。
  • keyEdgeFlags :这表示键应该对齐到哪条边。
  • isRepeatable :如果按住该键,它将不断重复输入。

方法.xml

该文件告诉系统可用的输入法子类型。我在这里只包含一个最小版本。

 <?xml version="1.0" encoding="utf-8"?>
<input-method
    xmlns:android="http://schemas.android.com/apk/res/android">

    <subtype
        android:imeSubtypeMode="keyboard"/>

</input-method>

4. 添加处理按键输入的Java代码

创建一个新的 Java 文件。我们称它为 MyInputMethodService 。该文件将所有内容联系在一起。它处理从键盘接收到的输入并将其发送到接收它的任何视图(例如 EditText )。

 public class MyInputMethodService extends InputMethodService implements KeyboardView.OnKeyboardActionListener {

    @Override
    public View onCreateInputView() {
        // get the KeyboardView and add our Keyboard layout to it
        KeyboardView keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard_view, null);
        Keyboard keyboard = new Keyboard(this, R.xml.number_pad);
        keyboardView.setKeyboard(keyboard);
        keyboardView.setOnKeyboardActionListener(this);
        return keyboardView;
    }

    @Override
    public void onKey(int primaryCode, int[] keyCodes) {

        InputConnection ic = getCurrentInputConnection();
        if (ic == null) return;
        switch (primaryCode) {
            case Keyboard.KEYCODE_DELETE:
                CharSequence selectedText = ic.getSelectedText(0);
                if (TextUtils.isEmpty(selectedText)) {
                    // no selection, so delete previous character
                    ic.deleteSurroundingText(1, 0);
                } else {
                    // delete the selection
                    ic.commitText("", 1);
                }
                break;
            default:
                char code = (char) primaryCode;
                ic.commitText(String.valueOf(code), 1);
        }
    }

    @Override
    public void onPress(int primaryCode) { }

    @Override
    public void onRelease(int primaryCode) { }

    @Override
    public void onText(CharSequence text) { }

    @Override
    public void swipeLeft() { }

    @Override
    public void swipeRight() { }

    @Override
    public void swipeDown() { }

    @Override
    public void swipeUp() { }
}

笔记:

  • OnKeyboardActionListener 监听键盘输入。在此示例中,它还需要所有这些空方法。
  • InputConnection 用于将输入发送到另一个视图,如 EditText

5.更新清单

我把它放在最后而不是第一个,因为它指的是我们已经在上面添加的文件。要将自定义键盘注册为系统键盘,您需要在 AndroidManifest.xml 文件中添加 service 部分。将其放在 application 之后的 activity 部分。

 <manifest ...>
    <application ... >
        <activity ... >
            ...
        </activity>

        <service
            android:name=".MyInputMethodService"
            android:label="Keyboard Display Name"
            android:permission="android.permission.BIND_INPUT_METHOD">
            <intent-filter>
                <action android:name="android.view.InputMethod"/>
            </intent-filter>
            <meta-data
                android:name="android.view.im"
                android:resource="@xml/method"/>
        </service>

    </application>
</manifest>

而已!您现在应该能够运行您的应用程序。但是,在设置中启用键盘之前,您不会看到太多内容。

6.在设置中启用键盘

每个想要使用您的键盘的用户都必须在 Android 设置中启用它。有关如何执行此操作的详细说明,请参阅以下链接:

这是一个摘要:

  • 转到 Android 设置 > 语言和输入法 > 当前键盘 > 选择键盘。
  • 您应该会在列表中看到您的自定义键盘。启用它。
  • 返回并再次选择当前键盘。您应该会在列表中看到您的自定义键盘。选择它。

现在,您应该可以在任何可以在 Android 中输入的地方使用键盘。

进一步研究

上面的键盘是可用的,但要创建其他人想要使用的键盘,您可能必须添加更多功能。研究以下链接以了解操作方法。

进行中

不喜欢标准 KeyboardView 的外观和行为?我当然不知道。貌似从安卓2.0开始就没更新过。 Play 商店中的所有自定义键盘怎么样?它们看起来一点也不像上面那个丑陋的键盘。

好消息是您可以完全自定义您自己的键盘外观和行为。您将需要执行以下操作:

  1. 创建您自己的子类 ViewGroup 的自定义键盘视图。您可以用 Button s 填充它,甚至创建您自己的子类 View 的自定义键视图。如果您使用弹出视图, 请注意这一点
  2. 在键盘中添加 自定义事件侦听 器接口。为 onKeyClicked(String text)onBackspace() 调用它的方法。
  3. You don’t need to add the keyboard_view.xml , key_preview.xml , or number_pad.xml described in the directions above since these are all for the standard KeyboardView 。您将在自定义视图中处理所有这些 UI 方面。
  4. 在您的 MyInputMethodService 类中,实现您在键盘类中定义的自定义键盘侦听器。这代替了不再需要的 KeyboardView.OnKeyboardActionListener
  5. 在你的 MyInputMethodService 类的 onCreateInputView() 方法中,创建并返回自定义键盘的实例。不要忘记将键盘的自定义侦听器设置为 this

原文由 Suragch 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题