这里面有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:GO
IME_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的背景中得到即可。然后就是对于每一个候选词进行绘制了。对于每一个候选词,得到其文本,然后计算其快读,然后再加上两边的空隙。然后就是判断是否选择了当前词:触摸的位置 + 滚动了的位置 如果是在当前词的左边到右边之间,则将高亮区域绘制在画布上面,高亮区域设置的大小即为当前词的大小,并且保存被选词的索引。最重要的还是需要将文本绘制在这个候选词的画布上面,它进行了一个判断,判断哪个才是推荐词。默认情况下是候选词的第一个词,但是它判断第一个词是否是合法的,如果是,则第一个词是候选词,否者第二个词才是候选粗,然后进行绘制。最后还需要绘制一条线,来分割各个候选词。上面提到的总共的宽度在所有的词都绘制出来之后,就能够得到了。最后面还有一个就是需要判断目标滚动是否是当前的,不是就需要滚动过去。
crollToTarget:滚到到目标区域。首选得到当前值,然后加上一个滚动距离,看是否超过了,然后进行调整即可,然后滚动到相应坐标。
setSuggestions:设置候选词。设置之后,就绘制即可。
onTouchEvent:触摸事件产生时调用。这里判断这个时间是什么:1.向上,则没动做;2.移动:如果是向左移动就要手动的选择候选词;3.如果是向上,也需要手动选择候选词。
takeSuggestionAt;选择在坐标x处的词,这个处理的是用户轻轻点击键盘,也就是选择候选词。
removeHighlight: 去除高亮显示。
总而言之,这个类是整个输入法的候选词类,目前还没有彻底的搞懂,需要调试才能搞懂,敬请期待吧。
SoftKeyboard.java:最为重要最为复杂的类,下次分解。