如何在 Android 中制作自定义键盘? [关闭]

2023-12-14

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

enter image description here


系统键盘

此答案告诉您如何制作可在用户安装在手机上的任何应用程序中使用的自定义系统键盘。如果您想制作一个仅在您自己的应用程序中使用的键盘,那么看我的另一个答案.

下面的例子看起来像这样。您可以针对任何键盘布局修改它。

enter image description here

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

1. 启动一个新的Android项目

我将我的项目命名为“自定义键盘”。随便你怎么称呼它。这里没有什么特别的。我会离开MainActivity和“你好世界!”布局原样。

2.添加布局文件

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

  • 键盘视图.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

键预览是按下键盘按键时弹出的布局。它只是显示您按下的键(以防您又大又胖的手指遮住了它)。这不是一个多项选择弹出窗口。为此,您应该查看候选人查看.

<?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文件

创建一个xml文件夹在你的res文件夹。 (右键点击res并选择新建 > 目录.)

然后将以下两个xml文件添加到其中。 (右键单击xml文件夹并选择新建 > XML 资源文件.)

  • number_pad.xml
  • 方法.xml

number_pad.xml

这就是事情开始变得更有趣的地方。这Keyboard定义了布局keys.

<?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%p不。不过,它可以被各个键覆盖,正如您在第三行中的删除和 Enter 键所看到的那样。
  • keyHeight:这里是硬编码的,但你可以使用类似的东西@dimen/key_height针对不同的屏幕尺寸动态设置它。
  • Gap:水平和垂直间隙表示按键之间留有多少空间。即使您将其设置为0px仍有一个小差距。
  • codes:这可以是 Unicode 或自定义代码值,用于确定按下该键时会发生什么或输入什么。看keyOutputText如果你想输入更长的 Unicode 字符串。
  • 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() { }
}

Notes:

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

5. 更新清单

我把它放在最后而不是放在前面,因为它引用了我们上面已经添加的文件。要将自定义键盘注册为系统键盘,您需要添加service部分到你的AndroidManifest.xml文件。将其放入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 设置 > 语言和输入 > 当前键盘 > 选择键盘。
  • 您应该在列表中看到您的自定义键盘。启用它。
  • 返回并再次选择当前键盘。您应该在列表中看到您的自定义键盘。选择它。

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

进一步研究

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

  • 创建输入法(安卓文档)
  • 软键盘(来自 Android 的演示自定义键盘的源代码)
  • 构建自定义 Android 键盘(教程) (源代码)
  • 在 Android 上创建自定义键盘(啧啧加教程)
  • 如何为 Android 创建自定义键盘(YouTube 视频:它是无声的,但我第一次学会了如何做到这一点。)

Going On

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

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

  1. 创建您自己的自定义键盘视图的子类ViewGroup。你可以用它来填充Button甚至可以创建您自己的自定义关键视图来进行子类化View。如果您使用弹出视图,那么请注意这一点.
  2. Add a 自定义事件监听器键盘上的接口。调用它的方法来进行类似的事情onKeyClicked(String text) or onBackspace().
  3. 您不需要添加keyboard_view.xml, key_preview.xml, or number_pad.xml在上述说明中进行了描述,因为这些都是针对标准的KeyboardView。您将在自定义视图中处理所有这些 UI 方面。
  4. In your MyInputMethodService类,实现您在键盘类中定义的自定义键盘侦听器。这是代替KeyboardView.OnKeyboardActionListener,不再需要。
  5. In your MyInputMethodService班级的onCreateInputView()方法,创建并返回自定义键盘的实例。不要忘记将键盘的自定义监听器设置为this.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Android 中制作自定义键盘? [关闭] 的相关文章

  • onActivityResult 中的完成活动不起作用

    我有一对必须同生共死的活动 基本上 AlphaActivity 会做一些工作 然后发送一个意图 startActivityForResult 对于 Beta 活动 当 Beta 活动完成时 我希望它发送一个意图 startActivity
  • android - EditText 打字速度很慢

    我的 EditText 在打字时响应速度很慢 这种滞后现象足以让我找到解决方案 我做了一些研究 发现了一个 SO 线程输入文本时 EditText 滞后 https stackoverflow com questions 6173591 a
  • 未找到 Gradle DSL 方法:“versionCode()”

    构建我的 Android 项目时遇到问题 我使用Grgit https github com ajoberstar grgit填写versionCode and versionName在 gradle 中 一切工作正常 直到我将 Andro
  • 合并两个位图图像(并排)

    任何人都可以帮助将两个位图图像合并为单个位图 在android中 并排 谢谢 尤瓦拉吉 您可以使用Canvas 查看这篇文章 http www jondev net articles Combining 2 Images in Androi
  • 为什么 Kotlin 数据类可以在 Gson 的不可空字段中包含空值?

    在 Kotlin 中你可以创建一个data class data class CountriesResponse val count Int val countries List
  • Android studio 在日志猫中“清除全部”,更改日志级别过滤器时日志仍然会回来

    在 LogCat 中 当我单击 全部清除 按钮时 它似乎清除了所有日志 但是 如果我更改日志级别并返回到之前的日志级别 则所有日志都会返回 例如 我正在查看 Verbose 我选择 全部清除 日志清除 我切换到 调试 我切换回 详细 现在所
  • doInBackground 运行时是否可以停止 asynctask?

    我正在 ActivityB Oncreate 中创建异步任务 在该任务中 我正在运行无限 while 循环doInBackground 当我转到上一个活动并再次回到该活动时 创建了另一个异步任务 我的问题现在是两个无限 while 循环正在
  • 如何编辑 gradle 依赖项

    我正在开发一个 android 项目 该项目在我的 gradle 文件中使用以下依赖项 compile com mapzen on the road 1 1 1 我想编辑其中一个文件 以添加一些缺少的功能并为该项目做出贡献 如何下载该项目并
  • MI设备中即使应用程序被杀死,如何运行后台服务

    您好 我正在使用 alaram 管理器运行后台服务 它工作正常 但对于某些 mi 设备 后台服务无法工作 我使用了服务 但它无法工作 如何在 mi 中运行我的后台服务 MI UI有自己的安全选项 所以你需要的不仅仅是上面提到的粘性服务 你需
  • 如何在 Android 清单文件中设置文本外观?

    是否可以做相当于 setTextAppearance context android R style TextAppearance Medium 在 Android 应用程序的清单文件中 android textAppearance and
  • Locale.getDefault().getCountry() 返回空字符串

    我正在尝试使用国家 地区代码获取用户语言 例如en US es es 但是当我使用Locale getDefault getCountry 它返回空字符串 虽然它给了我正确的语言Locale getDefault getLanguage N
  • Python Kivy - 在本机网络浏览器中打开 url 的应用程序

    我尝试制作一个简单的应用程序 在单击 Screen One 上的按钮后 在 Kivy 中打开一个网页 我使用了这个主题 Python 在应用程序中直接显示网络浏览器 iframe https stackoverflow com questi
  • 在 Android 中使用 iText 读取或打开 PDF 文件

    我是 Android 应用程序开发新手 使用 iText 我完成了 PDF 创建并在创建的文件上写入 现在我想阅读该 PDF 文件 如何使用 iText 打开或阅读 PDF 文件 例子将是可观的 那么提前 哪个是渲染 PDF 文件的最佳库
  • 如何在android中录制音频时暂停背景音乐

    我正在 Android 中开发一个音频记录应用程序 因此 如果设备音乐播放器中已播放任何背景音乐 则应在开始录制之前暂停该背景音乐 并且每当录制停止或暂停时 背景音乐都应恢复 播放录制的音频时也应该如此 有人可以帮我解决这个问题吗 提前致谢
  • 无法在 Android 模拟器中安装 apk

    我正在尝试通过 adb shell 在 ICS 模拟器中安装 apk 从一个站点下载 但出现以下错误 失败 INSTALL FAILED UID CHANGED 可能是什么问题 只需 rm r 有问题的数据目录即可 如果您在安装时遇到此错误
  • Google Android Drive api 在已安装版本上登录失败

    我开发了一个使用 GoogleDrive api 的 Android 应用程序 当处于调试状态或运行调试版本时 应用程序 工作正常 并正确验证附加的谷歌帐户 等 当我构建发行版本时 使用我的签名密钥 并且 安装apk文件 当我运行时 Goo
  • 将 System.Windows.Forms.Keys 序列转换为 Char

    有没有办法转换由 Keys 枚举表示的击键序列 即System Windows Forms Keys 在一个字符中 例如 Keys Oem4进而Keys A产生 char 它一定存在于 WinAPI 中的某个地方 因为当我在文本框中按下按键
  • 如何使 tablayout 文本大小相等?

    这就是我所做的 我为文本创建了一种样式
  • OpenGL ES 2.0 屏幕闪烁

    我面临着一个大问题 我正在使用带有 Android 4 0 3 的 Transformer tf101 选项卡 我的应用程序使用自定义 OpenGL ES 2 0 表面 我正在用纹理渲染多个平面 该纹理大约发生变化 每秒 20 次 并通过传
  • Android应用程序kill事件捕获

    我想在我的应用程序被终止时执行一些操作 可以使用哪种方法来实现此目的 我正在开发 Android 5 0 这个问题的关键在于 您必须了解您的申请是否可以收到任何 当您的应用程序在任何情况下被终止时的额外回调 下面的答案是由德文连线 http

随机推荐

  • Apache 中用于 POST/DELETE/PUT 的 URL 重写

    我的网址是这样的 http 10 243 123 1 v1 data register 我想重定向 重写这个网址到 https 10 243 123 1 data register This is HTTP POST PUT DELETE
  • 添加新行时,Google 表格条件格式会发生变化

    因此 我单击 A 和 1 之间的单元格来选择整个工作表 然后单击 格式 然后单击 条件格式 并设置规则 基本上 我有大约 15 种不同的条件 但所有条件都在 F 到 O 列中 所以我使用 F O 例如 如果文本恰好是 是 则将背景更改为绿色
  • 如果水平进度条位于工具栏上方,则不可见(适用于 Android 5)

    我尝试通过以下 XML 将水平进度条放置在工具栏顶部 my activity xml
  • hadoop getmerge到另一台机器

    是否可以存储输出hadoop dfs getmerge命令到另一台机器 原因是我的本地机器没有足够的空间 作业输出为 100GB 我的本地存储为 60GB 另一个可能的原因可能是我想在另一台机器上本地处理另一个程序中的输出 并且我不想将其传
  • R data.table 使用标准名称创建新列

    我想根据比率计算为我的 data table 创建新列 我的变量的名称有点标准 所以我认为必须有一种方法可以轻松实现这一点数据表 但是我不知道如何实现这一点 以下是我的示例数据和代码 set seed 1200 ID lt seq 1001
  • 复数 FFT 然后逆 FFT MATLAB

    我正在使用 Matlab 中的 FFT 函数来尝试分析行波激光模型的输出 模型的时域形式为 实数 虚数 其思想是将 FFT 应用于复数输出 以获得频域中的相位和幅度信息 load time domain field data data lo
  • 为什么我不能使用 boost::variant 访问这个自定义类型?

    下面的代码 include
  • 如何通过 Gmail 使用简单的 SMTP 命令发送电子邮件?

    出于教育目的 我需要使用 SMTP 的基本且简单的规则通过 SMTP 服务器发送电子邮件 我能够使用smtp4dev I telnet localhost 25和 命令是 我想做同样的事情 使用 Gmail SMTP 服务器 但是 它需要身
  • 如何按两个值对这个元组列表进行排序?

    我有一个元组列表 2 Operation SUBSTITUTED 1 Operation DELETED 2 Operation INSERTED 我想用两种方式对此列表进行排序 首先按升序排列第一个值 即1 2 3 etc其次是按相反字母
  • 如何处理 Start-Job 中运行命令的错误?

    我正在编写一个自动化脚本 我有一个函数 它接受命令或可执行文件 我必须等到命令或可执行文件完成运行并在失败或通过时返回 我还想将输出写入文件 我正在尝试与Start Job cmdlet 我当前的代码 job Start Job scrip
  • 与对象更改通知相比,Google Club Pub/Sub 的可扩展性如何

    正如标题所问 当使用签名 URL 上传对象时 与 Google Cloud Storage 中的对象更改通知相比 Google Club Pub Sub 的可扩展性如何 在能够处理短时间内上传的许多对象方面 每种方法的比较如何 如果上传的对
  • 如何将 Robomongo 连接到 MongoDB

    我的运行系统中有 MongoDB 和 Robomongo 并且我使用 Robomongo 作为客户端 我已经在另一个系统上安装了 MongoDB 我将其视为服务器 并且我想将我的系统 作为客户端 的 Robomongo 连接到另一个系统 服
  • 将值添加到选定的多选

    我想知道是否可以动态添加新值选择 js多重选择 类似于标记的工作方式 我在另一个看到过SO post用户说这是可能的 他链接到一个example and a fork在 github 上 但我在实现这些方面遇到了一些困难 源代码是用 Cof
  • 使用开源库时,我们应该针对源代码还是二进制文件进行编译? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 在项目中使用开源库 例如 SharpPcap 或 FakeItEasy 时 我们应该将源代码添加到解决方案中还是针对 DLL 进行编译并将它们放在解决方案中的目录中 您应该使用二进制文件进
  • 检查应用程序是否在前台或后台运行(使用同步适配器)

    我知道这是一个重复的问题 但我查遍了所有地方 找不到适合我的解决方案 所以 我有一个从 TMDB API 获取电影数据的应用程序 它使用同步适配器按页获取它 基本上它运行得很好 除非在应用程序打开且用户不在第一页时运行同步适配器的定期同步
  • MySQL 服务器在 Perl 爬行期间消失了

    我使用 WWW Mechanize 库来获取 URL 的内容并将其数据保存到 mysql 表中 但是当页面内容太大时 会出现以下错误消息 DBD mysql st 执行失败 MySQL 服务器已消失 F crawling perl test
  • 正则表达式删除字符串中的最后一个单词+附加字符

    我从服务器获取一个字符串 我必须使用正则表达式来解析它 我知道如何使用字符串函数 String split 等 来做到这一点 但不知道如何使用正则表达式 这是家庭作业要求中的 字符串看起来像这样 12345
  • 为什么该决策树每一步的值之和不等于样本数?

    我正在阅读有关决策树和装袋分类器的内容 并且我试图展示装袋分类器中使用的第一个决策树 我对输出感到困惑 from sklearn model selection import train test split from sklearn da
  • 为什么我收到 You do not have permission to call SpreadsheetApp.openById?

    我们有两张 AL 表 本地的和国家的 我正在尝试获取它 以便当我们当地的 AL 日历 完成时 数据会复制到国家日历中 检查编辑的单元格是否位于国家电子表格中某人的行中 然后将其复制到国家电子表格上的相应行中 我不断得到 您无权调用 Spre
  • 如何在 Android 中制作自定义键盘? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我想做一个定制键盘 我不知道如何使用 XML 和 Java 来做到这一点 下图是我想做的键盘模型 它只需要数字 系统键盘 此答案告诉您如何制作可在用户安装在手机上的任何应用程序中