【问题标题】:How do I implement custom View for keyboard after Keyboard has been deprecated?弃用键盘后如何为键盘实现自定义视图?
【发布时间】:2019-12-29 06:25:25
【问题描述】:

我正在使用最新的 Android Studio 和 Kotlin 为 Android(API 100% 用户)制作系统键盘。我正在尝试关注IME life cycle

有这个关于覆盖 onCreateInputView() 的指南

override fun onCreateInputView(): View {
    return layoutInflater.inflate(R.layout.input, null).apply {
        if (this is MyKeyboardView) {
            setOnKeyboardActionListener(this@MyInputMethod)
            keyboard = latinKeyboard
        }
    }
}

其中 MyKeyboardView 是一个自定义实现 KeyboardView 的实例,它呈现一个键盘。

问题只是因为 android.inputmethodservice.KeyboardView 自 API 级别 29 以来已被弃用。文档说

此类已弃用,因为它只是一个方便的 UI 小部件类,应用程序开发人员可以在现有公共 API 之上重新实现。

我不想使用已弃用的功能,但指南尚未更新以说明此更改。制作我自己的残酷方式只是在约束布局中制作大量按钮。这是正确的方法吗?作为一个完整的初学者,一旦我无法遵循指南,我就会迷失方向。

【问题讨论】:

  • 老实说,因为它工作得很好并且重新实现没有意义,所以我会禁用已弃用的 lint 并使用它。
  • 如果您在 Google 上搜索“Android,为什么不推荐使用键盘类?”,您不会得到一个好的答案。也许没有好的答案。
  • 在这里,谷歌的建议以及我是如何做到的stackoverflow.com/a/63689954/3101777

标签: custom-keyboard


【解决方案1】:

很明显,来自文档here

此类已在 API 级别 29 中弃用。此类已弃用 因为这只是应用程序的一个方便的 UI 小部件类 开发人员可以在现有的公共 API 之上重新实现。如果你 已经依赖这个类,考虑复制 从 AOSP 实施到您的项目或重新实施 自己做的类似小部件

这意味着您必须使用所有键创建自己的视图,这也意味着处理所有点击事件,例如输入、删除和切换键盘。自己给符号等

其实有很多方法可以做到。但我会尝试给您一个简单的想法,您将遵循您在使用已弃用的KeyboardView 时使用的大部分步骤:

首先创建您的自定义键盘布局,您可以使用任何方便的布局,例如 LinearLayoutRelativeLayoutButtons 用于按键等。我使用了 GridLayout 和 @ 987654327@s.

然后照常创建InputMethodService的子类:

public class MyIMService extends InputMethodService implements View.OnClickListener {

    private static String TAG = "MyIMService";

    @Override
    public View onCreateInputView() {
        View myKeyboardView = getLayoutInflater().inflate(R.layout.key_layout, null);
        Button btnA = myKeyboardView.findViewById(R.id.btnA);
        btnA.setOnClickListener(this);
        //ADD ALL THE OTHER LISTENERS HERE FOR ALL THE KEYS
        return myKeyboardView;
    }

    @Override
    public void onClick(View v) {
        //handle all the keyboard key clicks here

        InputConnection ic = getCurrentInputConnection();
        if (v instanceof Button) {
            String clickedKeyText = ((Button) v).getText().toString();
            ic.commitText(clickedKeyText, 1);
        }
    }
}

正如我之前所说,您可以尝试一种不同的方式来处理所有点击事件。但这应该会给你基本的想法。

就是这样。您必须像往常一样在清单文件中添加此服务,并且像往常一样添加其他步骤。现在应该可以了。

更新 Kotlin 版本:

class MyIMService : InputMethodService(), View.OnClickListener {
    override fun onCreateInputView(): View {
        val myKeyboardView: View = layoutInflater.inflate(R.layout.key_layout, null)
        val btnA: Button = myKeyboardView.findViewById(R.id.btnA)
        btnA.setOnClickListener(this)
        //ADD ALL THE OTHER LISTENERS HERE FOR ALL THE KEYS
        return myKeyboardView
    }

    override fun onClick(v: View) {
        //handle all the keyboard key clicks here
        val ic = currentInputConnection
        if (v is Button) {
            val clickedKeyText: String = (v as Button).getText().toString()
            ic.commitText(clickedKeyText, 1)
        }
    }

    companion object {
        private const val TAG = "MyIMService"
    }
}

【讨论】:

  • 我正在考虑使用您的解决方案,但我有疑问,因为自 api 29 以来我找不到任何有关如何处理事情的官方资料;这是唯一的方法吗?
  • @Nayk0 因为他们已经弃用了KeyboardView 和其他相关的类,他们将来会删除它。所以consider copying the implementation from AOSP into your project or re-implementing a similar widget by yourselves
  • 好的,谢谢。现在,如果我只需要使用 api
  • @Nayk0 他们不会立即删除它,但是一旦他们这样做了,您将无法使用 sdk(在其中删除它)编译您的代码(因为该类不存在)。因此,如果您不关心未来的支持,那就继续吧。
  • 如何将服务与视图绑定?
猜你喜欢
  • 2012-09-30
  • 1970-01-01
  • 2012-10-02
  • 1970-01-01
  • 1970-01-01
  • 2017-12-01
  • 2014-09-27
  • 1970-01-01
  • 2019-01-05
相关资源
最近更新 更多