开发一款方言输入法Android App(二)

上一篇主要提出了这款app的基本需求。接下来就是按照这个需求进行设计了。

消息传递

要想设计一个输入法,必须知道,在输入法中按下一个按键之后,究竟发生了什么,由于中文输入比英文复杂,且具有代表性,这里用一个简单的输入的活动图进行说明:

消息传递

当键入字母后,会通过方法进行判断当前的键盘是不是中文键盘,如果是,会把键入的信息添加到一个StringBuilder的实例composingText中,然后在字典中查找相应的汉字,然后在候选栏显示,然后是进行选字,选完字后,还会在候选栏中出现联想字,然后你可以继续选择,完成一次输入。在英文键盘和符号键盘中输入时,没有候选栏,直接提交。

输入法的初始化

了解了输入法基本的消息传递机制后,就可以开始具体的编写,首先进行的是输入法的初始化。输入法的初始化不同于一般的Android app.Android系统有它特有的输入法框架IMF,它给出了输入法必须的API.该框架的类也是各种让人眼花缭乱,我着重关心InputMethodService类,这也是初始化输入法的地方,显然,这个类是一个Service,需要在AndroidManifest.xml中使用android:permission声明所需要的服务,这里指的是BIND_INPUT_METHOD,这是api要求的。输入法启动了InputMethodService,执行onCreate()进行相关类的初始化,onCreateInputView()创建键盘视图,onCreateCandidateView创建候选栏视图。
onCreate()代码:

1
2
3
4
5
6
7
8
public void onCreate() {
super.onCreate();
mKeyboardSwitch = new ImeKeyboardSwitch(this, R.xml.pinyin);
mEditor = new PinyinEditor();
mWordDictionary = new PinyinDictionary(this);
mPinyinPhrase = new PinyinPhrase(this);
effect = new ExtraEffect(this);
}

onCreateInputView()代码:

1
2
3
4
5
6
public View onCreateInputView() {
inputView = (ImeKeyboardView) getLayoutInflater().inflate(
R.layout.keyboardview, null);
inputView.setOnKeyboardActionListener(this);
return inputView;
}

onCreateCandidateView代码:

1
2
3
4
5
6
public View onCreateCandidatesView() {
container = (Container) getLayoutInflater().inflate(R.layout.container,
null);
container.setCandidateViewListener(this);
return container;
}

以上就是初始化的主要代码。

键盘布局的实现

在Android输入法开发过程中,输入法的键盘布局的详细设计是通过xml文件的内容描述来完成的,键盘xml文件是储存在res/xml路径中。本文设计的输入法一共有三类键盘,中文键盘、英文键盘和符号键盘。在设计这些键盘时,首先定义键盘的相关属性,然后只需在完成键盘按键的位置和Unicode值的说明,然后加上按键的标签即可。键盘属性包括如下部分:

  • xmlns:android定义键盘视图的命名空间;
  • android:keyWidth="10%p"定义按键宽度,这里一个普通按键是10%;
  • android:horizontalGap="0px"定义键盘水平间隔距离,绝对值;
  • android:verticalGap="0px"定义键盘垂直间隔距离,绝对值;
  • android:keyHeight="@dimen/key_height"定义按键高度;

这部分完成后就要分别定义每个按键的属性,主要包括android:codes和 android:keyLabel,根据Google Android官方API说明,前者是按键的unicode值,而后者是按键的文本标签。同时在row中开始和结尾都要使用android:keyEdgeFlags来进行左右对齐调整。如英文键盘按键q的完整说明是:

1
2
<Key
android:codes="113" android:keyLabel="q" android:keyEdgeFlags="left"/>

在这里还要说明一下,android:popupKeyboard表示长按按键后弹出的键盘,布局文件也在res/xml下,在这里实现相关键盘键盘定义。比如我的中文键盘中:

1
2
3
<Key android:keyLabel="瓜"
android:keyOutputText="瓜娃子"
android:keyEdgeFlags="left" />

虽然本软件的要切换的键盘视图比较多,而且有很多长按的弹出视图,但是基本上都是通过以上方法进行布局。