1 功能需求
- 触屏设备主界面中有一个文本编辑框,底部区域固定显示一个数字键盘,键盘中除数字键外,还带有*和#键功能;
- 提供一个自定义的数字输入法,生成apk安装包文件,嵌入到img镜像文件中去。
2 设计思路
- 借鉴Android SDK目录下Sample中的 SoftKeyboard这个例子,参考demo演示,模仿实现IME(Input Method Editor);
- 在平台版本Android 1.5、SDK版本3、版本名称CUPCAKE版本之后,Android就开放它的IMF(Input Method Framework),让我们能够开发自己的输入法。而开发输入法最好的入手例子就是SoftKeyboard,虽然这个例子只是简单的英文和数字等的输入,但是它本身也算是写得非常清楚和完整的输入法实现。
3 源码分析
3.1 生命周期
接下来我们介绍一些比较重要的生命周期方法
onCreate()
输入法创建过程时,首先调用该方法进行输入法组件的主要初始化,该方法只会调用一次。
onCreateInputView()
当需要去生成用于创建输入的视图时,会调用此方法。在首次显示你的输入法时,以及每次由于配置更改而需要重新创建输入法时将被调用。
onCreateCandidateView()
当需要去生成用于显示候选键的视图时,会调用此方法,类似onCreateInputView()方法。
onStartInputView()
当输入视图正在显示并且在新的编辑框上开始输入时被调用。这将始终在onStartInput()方法之后被调用,允许你在此处进行常规设置(设置空格键Icon,并刷新整个键盘视图)和仅进行特定视图的设置(将所选键盘应用于输入视图)。你应该保证onCreateInputView方法在该方法被调用之前调用。
onCurrentInputMethodSubtypeChanged()
子类型改变时被调用。设置空格键Icon,并刷新整个键盘视图。
onFinishInput()
用户完成字段编辑后,将调用此方法。我们可以使用它来重置我们的状态。比如清除当前的已输入文字和候选内容,还有控制候选键显示区域的可见性。默认情况下它是隐藏的。
onDestroy()
输入法服务结束时调用,只调用一次,在方法中做好资源释放的工作。
3.2 实现原理
- 自定义输入法相关的类,都放在com.example.android.softkeyboard包的下面
- 在AndroidMainifest.xml中声明输入法组件
在清单文件中声明输入法服务,以及申请绑定输入法权限。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.softkeyboard">
<application android:label="@string/ime_name">
<service android:name="SoftKeyboard"
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>
<activity android:name=".ImePreferences" android:label="@string/settings_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
</application>
</manifest>
- CandidateView.java
CandidateView类是一个候选键的视图类,它直接继承于 View类即可。在用户输入字符时,它应该能根据字符显示一定的提示,比如拼音同音字,联想的字之类的情况。
类中主要的方法如下
/**
* 是设置宿主输入法,用于回到服务的连接以与文本字段进行通信。
*
* @param listener
*/
public void setService(SoftKeyboard listener) {
mService = listener;
}
/**
* 设置候选词,之后进行绘制候选键视图。
* @param suggestions
* @param completions
* @param typedWordValid
*/
public void setSuggestions(List<String> suggestions, boolean completions,
boolean typedWordValid) {
clear();
if (suggestions != null) {
mSuggestions = new ArrayList<String>(suggestions);
}
mTypedWordValid = typedWordValid;
scrollTo(0, 0);
mTargetScrollX = 0;
// Compute the total width