输入法中核心类是InputMethodService
输入法API
输入法相关的类可以在 android.inputmethodservice
和 android.view.inputmethodpackages
中找到。 KeyEvent
类在处理键盘字符中非常重要。
输入法的核心组件是一个服务,它是一个继承自 InputmethodService
的类。除了实现常规的输入法声明周期外,该类还包含了一些回调函数,用来给开发者处理输入法界面,处理用户输入,并将文本发送给当前正在处理的文本域。默认情况下, InputmethodService
类提供了管理输入法状态、可视化以及和当前输入法框交互的大部分实现。
下面的类也非常重要:
BaseInputConnection
定义了从输入法回到当前接收输入的应用之间的通信管道。你可以使用它来获取焦点所在位置周围的文本,向文本域提交文本以及向应哟功能程序发送原始的键盘事件。应用应该继承这个类而不要独自实现基础的 InputConnection
接口。
KeyboardView
继承自 View
,用来渲染绘制一个键盘,并且响应用户的输入事件。键盘的布局就是用一个 Keyboard
的实例来实现的,你可以通过创建一个xml文件来实现。
设计输入法的用户界面
输入法中主要有两种可视化的元素:输入界面和候选界面。你只需要实现和你设计的输入法有关的界面。
输入界面
输入法界面是用户输入文本的地方,可以是敲击键盘键位,手写,或者手势的形式。当输入法第一次调用显示的时候,系统会调用 onCreateInputView()
。在方法实现中,你可以创建想显示的布局,并将创建的布局实例返回给系统,
候选界面
候选界面是输入法为用户提示预测纠错和建议选词的地方。在输入法的生命周期中,当候选界面准备显示的时候,系统会调用 OnCreateCandidateView()
处理不同的输入类型
Android中的文本域允许开发者指定一个具体的输入类型,比如自由格式的文本,数字,URL,邮箱地址和查询字符串等。当你实现一个新的输入法的时候,你需要去检测每一个输入域的类型,并且为他提供合适的输入法实例。当然,你不需要去检测用户输入的数据在特定的输入类型中的合理性,那是应用的开发者的责任。
当一个输入域得到输入焦点并且启动你的输入法的时候,系统会调用 onStartInputView(),并且传入一个 EditorInfo对象参数,里面包含了关于输入类型和其他文本域属性的细节,在这个对象中, inputType字段包含了文本域的输入类型。
inputType字段是一个整型变量,它包含了基于位的规则表示各种各样的输入类型设置。若需要用它来检测不同的输入类型,用它和常量 TYPE_MASK_CLASS进行如下操作:
**inputType & InputType.TYPE_MASK_CLASS **
输入类型的位模式可以是下面多种值之一:
-
TYPE_CLASS_NUMBERA 输入数字的区域,就像前面截图中展示的那样,拉丁键盘在这种输入模式下显示了一个数字面板。
-
TYPE_CLASS_DATETIMEA 用于输入日期和时间的文本域。
-
TYPE_CLASS_PHONEA 用于输入电话号码的文本域
-
TYPE_CLASS_TEXTA 可以输入所有支持的字符的文本域。
这些常量在参考文档 InputType中,有更加详细的描述。
输入类型还包括其他的数值,表示普通文本输入的变体,例如:
-
TYPE_TEXT_VARIATION_PASSWORDA 用于输入密码的 TYPE_CLASS_TEXT的变体,输入法会将输入的字符显示为圆点。
-
TYPE_TEXT_VARIATION_URIA 用于输入URL和URI的 TYPE_CLASS_TEXT变体。
-
TYPE_TEXT_FLAG_AUTO_COMPLETEA 用于输入可以通过词典、查询或者其他组件自动完成的文本。
要用这些常量检查输入类型的时候,注意要用正确的常量去和 inputType相与,可用的常量列表包含在文档 InputType中。
从输入法向应用程序发送文本
当用户使用你开发的输入法输入文本时,你可以发送独立的键盘事件或者编辑光标所在的文本,来将文本发送到应用程序。在任何一种情况中,你可以使用一个 InputConncetion实例来发送文本,可以通过调用 InputMethodService.getCurrentInputConnection()来获得实例。
编辑光标所在文本
在一个文本框中处理文本的时候, BaseInputConnection类中包含了一些有用的方法:
getTextBeforeCursor()
返回一个包含光标前指定个数的字符 CharSequence
getTextAfterCursor()
返回一个包含光标后面指定个数的字符 CharSequence
deleteSurroundingText()
删除光标前后指定个数的字符
commitText()
提交文本并且重新设置光标的位置。
例如,下面的代码片段展示了如何用文本『Hello』替换文本『Fell』左边的内容。
InputConnection ic = getCurrentInputConnection();
ic.deleteSurroundingText(4, 0);
ic.commitText("Hello", 1);
ic.commitText("!", 1);
发送前组织文本
如果你的输入法支持文本预测或者需要多个步骤来组成一个符号或者单词,你可以在文本编辑区域展示这个过程,直到用户最终提交了这个单词,然后你可以用完整的文本替换掉部分的编辑中的文本。你可以在间断的通过 InputConnection#setComposingText()
提交文本。
下面的代码展示了如何在文本域中显示过程:
InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
...
ic.setComposingText("Composin", 1);
...
ic.commitText("Composing ", 1);
就说这么多吧,上代码了,注释还算详细吧
需要自定义输入法的各位司机拿走不谢。如有问题沟通可加我qq4160218
public class DeepBlueIME extends InputMethodService implements OnKeyboardActionListener, OnClickListener {
private KeyboardView kv;
private View handView;
private View cand