如何在键盘被弃用后为键盘实现自定义视图?

How do I implement custom View for keyboard after Keyboard has been deprecated?

我正在使用最新的 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 以来已被弃用。文档说

This class is deprecated because this is just a convenient UI widget class that application developers can re-implement on top of existing public APIs.

我不想使用已弃用的功能,但指南尚未针对此更改进行更新。制作我自己的残酷方法只是在约束布局中制作大量按钮。这是正确的方法吗?作为一个完全的初学者,我一听不懂就迷路了。

很明显,来自文档 here :

This class was deprecated in API level 29. This class is deprecated because this is just a convenient UI widget class that application developers can re-implement on top of existing public APIs. If you have already depended on this class, consider copying the implementation from AOSP into your project or re-implementing a similar widget by yourselves

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

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

时使用的大部分步骤

首先创建您的自定义键盘布局,您可以根据自己的方便使用任何布局,例如 LinearLayoutRelativeLayoutButtons 作为按键等。我用了 GridLayoutButtons.

然后照常创建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"
    }
}