为输入文本框或其他视图创建一个输入法,需要继承InputMethodService类。InputMethodService提供了很多的输入法的基础实现,管理状态的条款、输入法的可见度、与当前可见的Activity沟通.
一个好的出发点是SDK里提供的SoftKeyboard样例,也可以修改样例代码去建立你自己的输入法。
输入法像应用和服务一样被打包。在AndroidManifest.xml文件中,把输入法作为一个服务(Service)来声明,附带一些适当的intent过滤器和一些相关的元数据: -----------------------------------------------------------------------------------------------------
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.fastinput">
<application android:label="@string/app_label">
<!-- Declares the input method service -->
<service android:name="FastInputIME"
android:label="@string/fast_input_label"
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>
<!-- Optional activities. A good idea to have some user settings. -->
<activity android:name="FastInputIMESettings" android:label="@string/fast_input_settings">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
</application>
</manifest>
-----------------------------------------------------------------------------------------------------
假如你的输入发允许用户去调整一些设置,你应该提供一个可以运行在设置应用上的设置页面。这是可选的,你也可以选择在IME的UI上直接提供所有的用户设置.
下图为一个输入法的生命周期:
视觉元素:
输入法有两个主要的视觉元素:输入视图和候选视图。假如其中有一个是不相关的你的输入法的经验,你不必遵循这种风格, 输入视图: 就是用户可以按键、手写或其他手势视图。InputMethodService.onCreateInputView()被调用时,输入法第一时间被显示。创建并返回你想要显示的输入法窗口视图等级。
候选视图: 潜在的、提交用户选择的,可以关联,也可以不关联到你的输入法,默认的行为是,当调用InputMethodService.onCreateCandidatesView()时,你可以返回null。
设计不同的输入类型: 一个应该的文本域可以有不同的输入类型指定在它们上,例如,自由形式的输入法,数字,URL,E-mail地址和搜索。当你实现一个输入法的时候,你需要注意到不同的输入类型。输入法不能自动的替换输入类型,所以你需要在你的IME上支持所有的类型。然而,输入法是不负责验证输入发送到应用程序,这就是应用程序的责任。例如,LatinIME提供了android平台文本和电话号输入的不同布局:
InputMethodService.onStartInputView(),携带一个包含关于输入类型和应用程序的文本字段的其他属性的细节的EditorInfo被调用。
(EditorInfo.inputType & EditorInfo.TYPE_CLASS_MASK)可以是许多不同的值,包括:
TYPE_CLASS_NUMBER
TYPE_CLASS_DATETIME
TYPE_CLASS_PHONE
TYPE_CLASS_TEXT
EditorInfo.inputType可以包含其他掩盖位,表明了类变化和其他标志。例如,TYPE_TEXT_VARIATION_PASSWORD或TYPE_TEXT_VARIATION_URI或TYPE_TEXT_FLAG_AUTO_COMPLETE。
密码域
注意不要在你的界面中显示密码,除了提醒用户外也不要把密码保存起来。把输入文本传给应用
有两种方法可以发送文本到应用。您可以发送单独的按键事件,也可以编辑周围应用程序的文本字段光标文本。
要发送一个按键事件,您可以简单地构造KeyEvent对象,并调用InputConnection.sendKeyEvent()。下面是一些例子:
--------------------------------------------------------------------------------------------------
InputConnection ic = getCurrentInputConnection();
long eventTime = SystemClock.uptimeMillis();
ic.sendKeyEvent(new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, keyEventCode, 0, 0, 0, 0,
KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
ic.sendKeyEvent(new KeyEvent(SystemClock.uptimeMillis(), eventTime,
KeyEvent.ACTION_UP, keyEventCode, 0, 0, 0, 0,
KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
-----------------------------------------------------------------------------------------------
或者,利用方便的方法:
-----------------------------------------------------------------------------------------------
InputMethodService.sendDownUpKeyEvents(keyEventCode);
-----------------------------------------------------------------------------------------------
注:建议使用诸如因为可能适用每按一个键后的文本过滤器的电话号码领域的某些领域上面的方法。返回键和删除键也应被作为某些输入类型的原料主要活动,如应用程序可能为特定关键事件看,以执行一个动作。
当编辑文本字段的文本时,android.view.inputmethod.InputConnection一些更有用的方法有:
-----------------------------------------------------------------------------------------------
getTextBeforeCursor()
getTextAfterCursor()
deleteSurroundingText()
commitText()
例如,假设文本“Fell”是左边的光标和你想代之以“Hello!”:
-----------------------------------------------------------------
1.InputConnection ic = getCurrentInputConnection();
2.ic.deleteSurroundingText(4, 0);
3.ic.commitText("Hello", 1);
4.ic.commitText("!", 1);
没有提交前的编写
如果您的输入法做一些预测的文本实物或需要多个步骤,组成一个字或字形,您可以显示,直到用户在文本领域的进展犯了字,然后您可以替换完成的文字部分组成。这次所组成的文本将被突出显示的文本字段中以某种方式,如下划线。
------------------------------------------------------
InputConnection ic = getCurrentInputConnection();
ic.setComposingText("Composi", 1);
....
ic.setComposingText("Composin", 1);
....
ic.commitText("Composing ", 1);
六.拦截硬件按键消息
尽管输入法窗口没有foucs,但是它最先收到硬件的按键消息,如果需要处理这些硬件按键消息,你只需要
重写InputMethodService.onKeyDown() 与InputMethodService.onKeyUp(),如果你不想处理某个按键,记得调
用super.onKey* 。
七.其他注意点
1.提供一个用户可以直接从当前输入法进行相关输入法设置的方式。
2.提供一个用户可以切换不同输入法的方式。
3.让输入法界面尽快的弹出,资源或者耗时长的操作可以稍后加载。
4.当输入法窗口被隐藏的时候,大块的内存分配最好尽快释放
5.确保输入法能包含最常用的字符。