PinyinIME输入法开发

来源:互联网 发布:webshell检测 python 编辑:程序博客网 时间:2024/06/14 05:54

(转) 【小木桩】PinyinIME输入法开发

(2013-02-25 16:32:57)
转载
 分类:转贴
第一   开始
对于一个从来没有接触输入法的开发人员来说,如果你想自己开发输入法,那么下面的这些步骤是值得你一看的。至少这是我自己的开发经历,我想会对你有很大的帮助。
首先我想说的就是,如果你在别人项目的基础上开发自己的项目,那么有几点是必须做好的。
1、不要盲目的翻来翻去的看代码,这样的收获会很小很小,因为这个时候你甚至还不知道别人定义的字段都是代表什么,又谈何能看懂代码呢?
2、查看manifest文件,找到项目的入口处,这个很关键。
3、在看代码的过程中不要每一条语句都去深究,对于方法来说,掌握整理作用即可。
第二  准备
谷歌拼音输入法最主要的一个类是PinyinIME,这个类继InputMethodService。
原版的输入法是以这个类为基础,其他的一些类都是自定义键盘,候选框,popupwindow等,所以这些类我们都不需要了解,而且最终都用不到,因为我们要自己定义键盘。如果我们做的键盘需要用上下左右键来控制输入,那么普通的button是行不通的,因为下面的键盘获取不到焦点,所以键盘的button只能点击。所以这也就是说,如果你想实现一个用上下左右键来控制键盘输入的话,那么必须用view或者surfaceview来画键盘,这样才能用方向键控制输入。本人习惯用surfaceView,因为它更高级,更好用。
先看下面的一张图,这是原版输入法的键盘
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-132.png
接下来介绍PinyinIME类当中的各个字段都具体代表什么东西,只要清楚的知道它们是什么以后,我们才能看懂代码。
(1)EnglishInputProcessor  mImEn
这个字段是英文处理的一个类(无继承),当当前输入状态为英文输入时则调用这个类处理。
(2)InputModeSwitcher  mInputModeSwitcher
用于切换输入法的一个类,可以中文输入和英文输入两种切换
(3)SkbContainer  mSkbConTainer;
这个类继承了view,实现了很多监听方法,其实它就是下面的软键盘布局,此布局是画出来的,所以它无法获取焦点,而我们看到它获取焦点其实只是画出来的焦点。
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-18409.png
(4) LinearLayout  mFloatingContainer;
在中文输入状态下,这个布局存放的是用户输入的拼音,如下图
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-19679.png
上面的thjjh的布局就是LinearLayout。
(5) ComposingView  mComposingView;
它代表的是上面thjjh的第一个,在代码中有一条这样的语句
mComposingView = (ComposingView)mFloatingContainer.getChildAt(0);说明它代表的是mFloatingContainer中的第一个view。
(6)PopupWindow  mFloatintWindow;
前面我们已经谈到有这样一个viewfile:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-20221.png
那它又是通过什么方式显示出来的呢,  你猜对了。mFloatingContainer这个view就是放在mFloatintWindow,然后通过popupWindow的方式弹出来,给用户一个提示作用,它是否可见有代码控制
(7) PopupTimer   PopHander= new PopupTimer();
它是一个自定义继承Handler的类,里面含有一个线程,它的主要作用就是控制popupwindow的出现和消失。
  原版输入法中一共存在三种pupupwindow,如下图所示
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-28247.png
(一)白色背景g
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-21785.png
(二)白色背景弹出的 开始
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-28814.png
(三)白色背景的 thjjh英文
(8)CandidatesContainer    mCandidatesContainer
它是一个自定义继承RalativeLayout的布局,也可以说是一个view。它就是显示中文候选框的一个重要布局,如下图所示
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-5233.png
这也是中文输入法中的重要布局
(9)BalloonHint  mCandidatesBalloon
它是一个自定义继承popupwindow的类,由名字可以看出,“气球暗示”,它代表的就是上面提到的三个popupwindow中的第二个  “开始”
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-21943.png
(10)ChoiceNotifier    mChoiceNotifier
它是一个自定义继承Handler并实现一个监听接口的类。  在代码中我也暂时没有确切的了解它为何用,(待续……)
(11)OnGestureListener   mGestureListenerSkb
        监听软键盘手势动作的一个(手势)监听器
(12)OnGestureListener   mGestureListenerCandidates
        监听候选框手势动作的一个(手势)监听器
13GestureDetector  mGestureDetectorCandiadates
    候选框的手势传感器
14GestureDetector  mGestureDetectorSkb
    软键盘的手势传感器
(15)AlerDialog  mOptionDialog
       当长按键盘上面的“中文”时,便会弹出这个对话框,它是一个设置Dialog,如下图
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-7174.png
(16)PinyinDecoderSerViceConnection  mPinyinDecoderSerViceConnection
       用于启动拼音解码服务的一个回调连接
17ImeState  mImeState=ImeState.STATE_IDLE;
  这是一个枚举,记录着当前为何种输入状态,如空闲状态,预测状态等等。。。拼音解码服务会根据当前的状态来搜索相对应联想出来的中文。、
(18)DecodingInfo  mDecInfo=new  DecondingInfo();
      这是中文输入下最重要的一个类,用它来解析拼音,它的解析规则是这样的,用户输入一个拼音的字符串,然后DecodingInfo类根据这个pinyin字符串去词库当中搜索中文,然后返回很多很多中文存放在一个容器当中,然后我们可以从容器当中拿出这些解析好的中文,它返回的是一个list
第三   看代码
(1) onCreate()
  拼音输入法服务第一次运行起来的时候会执行这个方法(由系统调用),只会执行一次。所以可以在这个方法里面指定一些初始化的动作。
(2) Public View onCreateInputView()
  创建软键盘的view,然后在这里面设置监听等等,各种初始化动作,此方法由系统调用也只执行一次。
创建好了软件盘view之后,就 returnview;返回,之后view就有系统调用它是否弹出来。
(3)public  View  onCreateCandidatesView()
  此方法是创建候选框的view,由系统调用,当然我们也可以将中文的候选框view直接嵌入到然键盘view当中去,因为我就是这么做的。那么这里就可以返回null。这样一来,我们就省得自己反复控制候选框view是否可见了。当然,软键盘也就会更复杂了一点。
上面上个步骤是很重要的,一切监听做好了之后,输入法就由系统控制运行了。每一次运行输入法的时候会执行如下方法
onStartInputView(EditorInfo editorInfo,booleanrestarting)
此方法里面有一个重要的参数editorInfo,因为文本输入框可能有多重形式,如果只运行数字输入的edittext(电话号码),喊隐藏字符的 密码输入框,URL地址输入框等等,我们可以根据这是信息来对我们的软键盘进行相应的设置。
(4)onFinishInputView()
每一次输入法结束输入之后都会调用这个方法,我们可以让我们的键盘进行重置设置,比如记录一些数据也可以,具体需要做什么由我们自己而定
——————有了上面的四点之后,我们就可以大体的知道输入法的运行流程了,
接下来将介绍一些细节的方法,也是重要的方法
(1)、默认情况下,输入法是否为全屏是由系统控制的,然后如果我们要认为的控制它为全屏或者不为全屏的话。可以修改下面这个方法
Public boolean onEvaluateFullScreenMode()
当我们返回true的话,则为全屏,返回false的话则不为全屏。如果自己不想控制,则返回super.onEvaluateFullScreenMode();
(2)、在全屏模式下,上面的会有一个由系统定义的输入框,如下图
file:///C:/DOCUME~1/小木桩/LOCALS~1/Temp/ksohtml/wps_clip_image-14308.png
如果我们想自己定义上面的系统输入框,那么有以下几点是要遵行的。
改写public ViewonCreateExtractTextView()方法,返回自己定义的输入框布局。
在我们自定义的输入框布局中必须有这样一个控件  ExtractEditText,而且它的id必须为@android:id/inputExtractEditText  
接下来包含多少其它的控件都由自己设计,想有多花哨都行。
(3)、如果将字符串提交到输入框当中,如何删除输入框当中的字符串呢?方法如下:
提交字符串:
InputConnect ic=this.getCurrentInputConnection();
If(ic!=null){
  ic.commitText(“你好”,1);
}
这样便可以将你好提交到输入框,当前光标的后面去,1就是光标的位置。
如果你想提交回车键的话,用这种方法是提交不了的,那么用下面这条语句吧,它可以助我们提交一些转义字符
this.sendKeyChar(charc);  c就是我们要提交的转义字符
删除输入框的一个字符
InputConnect ic=this.getCurrentInputConnection();
If(ic!=null){
  ic.deleteSurroundingText(1,0);
}
第一个参数是删除光标左边字符的个数
第二个参数是删除光标右边的字符个数
这里我们填1,0是最好的方法,也即是普通的删除一样
(4)下面介绍中文解析类DecodingInfo,在源码中,此类已经被完全完全的融合到了它的候选框view当中,所以直接看它的这个类会特别的吃力,因为涉及了很多很多东西,所以下面我谈到的将以我改好的,通用的DecodingInfo类为例来进行说明,绝对的通用
  重要方法如下
正常情况下解析,即传入拼音字符串,然后解析出中文、
DecodingInfo decoding=new DecodingInfo ();
decoding.setStateInfo(Constant.NORMAL_SEARCH);
//设置解析方式为普通解析中文
decoding.setStringPinyin(“nihao”);
//设置要解析的拼音字符串
decoding.chooseDecodingCandidate(-1);
//开始解析
ArrayList list=decoding.listCandidates;
//拿数据
这样list当中只拿到了10个数据,那么如果要请求下一页的话,则执行
decoding.preparePage(4);
里面的整数4为你想要拿到的页码数据,但是在拿数据之前你要先判断一下到底还有没有数据,方法如下:
decoding.pageForwardable(4);
如果它返回true,那么代表第4页还有数据。
接下来执行:decoding.preparePage(4);
List.addAll(decoding.listCandidates);
//这样便将下一页的数据添加进来了。
预测状态下解析:
  如当你点击“你好”之后,那么可以由你好这两个词进行一次解析得到相应的联想数据,方法如下:
decoding.setStateInfo(Constant.PREDICT_SEARCH);
//设置解析类型
decoding.preparePredicts(“你好”);
//设置中文,并进行解析
ArrayList list=decoding.listCandidates;
//拿数据
后面的下一页怎么拿数据都和之前的一样。
        —————以上的介绍只是一部分,真正软键盘的定义由你自己而定,所有的控制也由自己控制。该有的方法上面已经统统概括。