Android SDK sample 之 SoftKeyboard

  • 格式:doc
  • 大小:45.00 KB
  • 文档页数:7

Android SDK sample 之SoftKeyboard在Android SDK( 我是2.1 )的Sample中,有一个SoftKeyboard的例子,这个应该是编写输入法的一个入口吧,下面我将尽心详细的解析。

我也是初次接触输入法层面,所以遇到不懂的可能需要查阅详细的资料。

这个例子设计的非常的简单。

按照它自己的解释是:这是一个软键盘输入法的例子。

代码追求的是完整性基础上的简单性,所以在一定程度上面它还不算是一个输入法(只有英文和数的输入以及一些标点)。

它的密度是为你提供一个基本的开始编写IME for Android的例子,你可以再在其之上进行适当的扩展。

那么它的文件组织是:AndroidMainifest.xml 这个是每一个Android应用都会有的一个配置描述文件。

具体的说明可以参见:AndroidManifest.xml 文件之详细解析。

那么对应到这个IME应用程序中他的一个特点是,他把自己声明成了服务,而且绑定在了输入法之上。

它的intent-filter是直接用的InputMethod接口,这也是所有的输入法的接口。

res 目录:这个是resource目录,即资源目录。

重要的有values,这个包括strings.xml以及一些你的一些自定义的值类型的xml文件。

这里面包括3个文件,一个就是strings.xml。

在这里定义了该输入法的名字,词的分隔符(就是你输入过程中可能用来表示一个词输入完成的符号,比如空格,标点等等),还有3个是为了软键盘来定义的,具体是定义了软键盘上的确认键。

这里在后面的代码中可以看到,他主要是根据输入框的信息,来设置EnterKey 的图标或者标示。

比如你在一个网址上面输入,他就会显示一个搜索的图标,而在编辑短信时,如果实在收信人写,那么EnterKey就是Next标签,用来直接跳到短信正文部分非常的方便。

然后就是dimens.xml,这个是软键盘的尺寸信息,包括键高,候选词字体的高度,候选词垂直间隙。

最后就是color.xml了。

他定义了候选词的背景颜色,比如正常,推荐,背景和其他等颜色。

另外的重要的目录就是layout了,顾名思义,就是布局配置文件。

这里只有一个配置文件:input.xml,它定义的是输入视图的信息,包括id,放置在屏幕下面,水平最大填充,垂直包含子内容即可。

最后一个非常重要的文件夹就是xml,将分别介绍之。

在这里面,最简单是method.xml。

该文件提供的是为搜索管理提供的配置信息(这个很诡异,暂时不明白)。

然后是qwerty.xml。

这个文件顾名思义就是全键盘的布局文件。

这种键盘布局文件非常的简单,首选需要声明这是一个键盘布局,需要一个Keyboard标签,然后就是一些属性。

keywidth 是键宽,%形式的就是比例,比如这里的10%p就是每个键占10%,所以一排就是10个键。

格式也很简单,就像是一个矩阵一样,一行一行的定义就行了。

每一行的一列,需要定义这个键的codes和label,以及最左边和右边的键。

有一个特别的就是这个文件的第二行,前面可以定义一个空隙,比如是占5%的位置,那么剩下的就只能安排九个键了,最后还会剩余5%在右边。

键不只是可以定义label,而且可以用icon,比如shift键,而且可以定制特殊键的键宽。

最后的一行我是没有怎么看懂的,因为它和这个Sample运行的时候的布局不一样,有待研究。

后面的几个xml文件都是不同的键盘布局而已。

还有一些drawable的文件,里面放置的是图标文件。

好了,除了源代码之外的所有配置都搞清楚了,下一步就是阅读源代码了。

终于到了解读源文件的时间了。

在src目录里面就是真个输入法的源文件了。

最开始我看的源文件是openwnn的源文件,这个开源的输入法实在是太强大了,然后很多地方我都还没有搞明白,作为入门级的,还是看这个Sample比较的简单吧,虽然他的功能并没有达到一个输入法的真正的情况,但是它却是经历了一个开发输入法的完整流程。

这里面有4个文件:LatinKeyboard.java:这个就是软键盘类了,直接继承了Keyboard类来实现一个输入拉丁文的键盘。

它还定义了一个内部类,叫做LatinKey,它直接继承了Key,来定义一个单独的键,它唯一重载的函数是isInside(int x , int y ),用来判断一个坐标是否在该键内。

它重载为判断该键是否是CANCEL 键,如果是则把Y坐标减少10px,按照他的解释是用来还原这个可以关掉键盘的键的目标区域。

在LatinKeyboard中,重载了一个createKeyFromXml的函数,这是一个回调函数,他是键盘在描绘键的时候调用,它是从一个xml资源文件中载入一个键,并且放置在(x,y)坐标处。

它还判断了该键是否是回车键,并保存起来。

这当中还定义了一个函数是:setImeOptions,它是根据编辑框的当前信息,来为这个键盘的回车键设置适当的标签。

这个很好理解,就如前面我说过的一样,输入框的不同,会产生不同的回车键的label或者icon。

在这个函数中,有一个技巧是用了一些imeOption的位信息,比如IME_MASK_ACTION等等。

主要是查看的EditorInfo的Action信息,这里有:IME_ACTION_GO:这个是go操作,它将用户带入到一个该输入框的目标的动作。

那么确认键将不会有icon,但是有label:GOIME_ACTION_NEXT:这个是是next操作,它将用户带入到该文本框的写一个输入框中。

比如说编辑短消息的时候,内容就是收件人手机号码框的next文字域。

它也只是一个NEXT label就行了。

IME_ACTION_SEARCH;这个是search操作,它的默认动作就是搜索。

比如在URL框中输入的时候,默认的就是search操作,它提供了一个像放大镜一样的icon。

IME-ACTION_SEND:这个是send操作,它的默认动作就是发送当前的内容。

比如在短消息的内容框里面输入的时候,后面通常就是一个发送操作。

它也是只提供一个Label:SEND DEFAULT: 默认情况下表示文本框并没有什么特殊的要求,所以只需要设置return的icon 即可。

至此,这个类就已经完毕了。

很简单一句话,定义一个xml格式的Keyboard的布局,然后吃继承一个Keyboard类,即可。

LatinKeyboardView.java这个类是这里面最简单的类了。

前面定义的keyboard类通常来说就只是一个概念而已,并不能实例出来一个UI,所以需要借助于一个VIEW类来进行绘制。

这个类简单的继承了KeyboardView类,然后很奇怪的重载了一个方法,就是onLongPress函数,这个函数是在有长时间按键事件的时候会调用。

它首先判断这个按键是否是CANCELJIAN键,如果是的话就给键盘发送一个OPTIONS键被按下的事件。

我的理解好像是屏蔽这个CANCEL键,然后发送了一个未知的代码的键而已。

Candidateview.java这个类是候选键的视图类,它直接继承于View类即可。

里面后很多的私有变量,让人很惆怅。

mService:这个是这个candidateView的宿主类,也就是该view是为什么输入法服务的。

mSuggestions:这个是建议。

比如说当我们输入一些字母之后输入法希望根据输入来进行联想建议。

mSelectedIndex:这个是用户选择的词的索引。

mSelectionHighlight:这个是用来描绘选择区域高亮的一个类。

mTypedWordValid;键入的word是否合法正确。

mBgPadding:背景填充区域。

mWordWidth;这个是对于候选词的每个词的宽度。

mWordX:这个是每个候选词的X坐标。

有了这两个变量,就能够在屏幕上准确的绘制出该候选键。

mColor*:这几个是定义了各种颜色。

mPaint:这个是一个绘图类,后面会用到mVerticalPadding;垂直填充区域。

mTargetScrollX:目标滚动的横坐标,即要将目标滚动到何处。

mTotalWidth:总的宽度mGestureDetector:这是声明一个手势监测器然后是各个方法,这个类设计得还是非常合理的。

CandidateView:构造函数,他的参数是context,这个是输入法能够传递给它的,应该是系统的上下文。

在这个类里面,主要是对一些变量的初始化工作。

首先初始化的是mSelectionHighlight,它本身是一个绘图类,用android的默认背景来初始化,然后设置了一下这个绘图的一些状态。

然后是对整个iew设置背景色,然后初始化各个color值。

注意的是,这个地方都是通过系统的资源管理器来进行资源的获取,而不是显示的使用。

然后初始化了一个手势检测器,它的Listener重载了一个方法,就是onScroll,这个类是手势检测器发现有scroll动作的时候触发。

在这个函数里,主要是进行滑动的判断,比如首先得到上一次的x坐标,加上本次移动的距离,看是否超过了最大宽度,或者是否越过了最小的最左边。

最后目标移动后距离就是sx,然后再将该视图移动到sx。

然后就是设置水平滚动中水平边是否需要褪色处理,设置这个候选视图是否需要draw自己,最后设置水平和垂直的滚动条是否需要显示。

setService是设置宿主输入法。

computeHorizontalScrollRange,这个是表示这个VIEW的水平滚动区域,返回的是候选视图的总体宽度。

onMeasure:重载的view类,它主要是在布局阶段被父视图所调用。

比如当父视图需要根据其子视图的大小来进行布局时,就需要回调这个函数来看该view的大小。

它首先计算自己的期望的宽度,调用resolveSize来看是否能够得到50px的宽度;然后是计算想要的高度,这里的计算我也没有怎么看懂:文本的字体大小+ 垂直的填充大小+ (高亮区域的上边+ 下边的坐标)。

后面括号里面的我就没有看懂,这两个边的值是坐标,这么加是什么意思呢。

最后需要注意的是,一定要调用setMeasureDimension来对宽和高进行保存,否则将会有异常出现。

onDraw: 重载它来进行画图的动作。

它提供了一块画布,如果为空,则直接调用父类来画。

首先需要判断是否有候选词,没有的话就不用绘制。

然后需要初始化背景的填充区域,直接view的背景中得到即可。

然后就是对于每一个候选词进行绘制了。

对于每一个候选词,得到其文本,然后计算其快读,然后再加上两边的空隙。

然后就是判断是否选择了当前词:触摸的位置+ 滚动了的位置如果是在当前词的左边到右边之间,则将高亮区域绘制在画布上面,高亮区域设置的大小即为当前词的大小,并且保存被选词的索引。