【Android源码 栏目提醒】:网学会员--在 Android源码 编辑为广大网友搜集整理了:android输入法02:openwnn源码解析02—Keyboard和KeyboardView - 网络与通信绩等信息,祝愿广大网友取得需要的信息,参考学习。
android 输入法 02:openwnn
源码解析 02—Keyboard 和 KeyboardView本文主要介绍 openwnn 对 Keyboard 和 KeyboardView 的处理。
这一部分主要涉及三个类:InputViewManager.java,DefaultSoftKeyboard.java,DefaultSoftKeyboardJAJP.java。
其中InputViewManager 是与键盘相关的对外接口,DefaultSoftKeyboard 是通用类,DefaultSoftKeyboardJAJP 是日文定制类。
1、InputViewManager 第一步我们先来看看 InputViewManager。
这个接口类代码很简单:java view plaincopy 1. / 2. TheinterfaceofinputviewmanagerusedbyOpenWnn. 3. 4. authorCopyrightC2009OMRONSOFTWARECO.LTD.AllRightsRese rved. 5. / 6. publicinterfaceInputViewManager 7. / 8. Initializetheinputview. 9. 10. paramparentTheOpenWnnobject 11. paramwidthThewidthofthedisplay 12. paramheightTheheightofthedisplay 13. 14. returnTheinputviewcreatedintheinitializeprocess codenullifcannotcreateainputview. 15. / 16. publicViewinitViewOpenWnnparentintwidthintheight 17. 18. / 19. Gettheinputviewbeingusedcurrently. 20. 21. returnTheinputviewcodenullifnoinputviewisusedc urrently. 22. / 23. publicViewgetCurrentView 24. 25. / 26. Notificationofupdatingparentsstate. 27. 28. paramparentTheOpenWnnobjectusingthismanager 29. / 30. publicvoidonUpdateStateOpenWnnparent 31. 32. / 33. Reflectthepreferencesintheinputview. 34. 35. paramprefThepreferences 36. parameditorTheinformationabouttheeditor 37. / 38. publicvoidsetPreferencesSharedPreferencesprefEditorInfoedito r 39. 40. / 41. Closetheinputview. 42. / 43. publicvoidclosing 44. 从这个接口文件中,我们可以看出在输入法处理中,对于键盘部分需要涉及的操作并不是很多。
2、配置项 这里我们先从简单的部分开始研究。
第一个是 setPreferences,这只配置项。
这一步的工作是读取与键盘部分有关的配置项,在生成键盘(改变键盘)时进行设置。
代码中设计到的配置项很减少,只有:震动、声音、是否自动切换大写。
在DefaultSoftKeyboard.java 中只设置了震动和声音,在DefaultSoftKeyboardJAJP.java 添加了是否自动切换为大写。
具体大家可以看代码,对于是否自动切换大写,从代码上看,我猜测,有些输入框默认是输入大写的。
(这一部分我想不到例子,谁有例子可以 share 一下)3、KeyboardView 在 InputViewManager 中有 initView 这个函数,实际上使用来生成KeyboardView 的。
其
源码如下:在 DefaultSoftKeyboard.java 中:java view plaincopy 1. /seejp.co.omronsoft.openwnn.InputViewManagerinitView/ 2. publicViewinitViewOpenWnnparentintwidthintheight 3. mWnnparent 4. mDisplayModewidth320PORTRAIT:LANDSCAPE 5. 6. / 7. createkeyboardsamptheview. 8. Tore‐ displaytheinputviewwhenthedisplaymodeischangedportraitlt‐ gtlandscape 9. createkeyboardseverytime. 10. / 11. createKeyboardsparent 12. 13. SharedPreferencesprefPreferenceManager.getDefaultSharedPrefe rencesparent 14. Stringskinpref.getStringquotkeyboard_skinquot 15. mWnn.getResources.getStringR.str ing.keyboard_skin_id_default 16. Log.dquotOpenWnnquotquotkeyboard_skinquotskin 17. intidparent.getResources.getIdentifierskinquotlayoutquotquotjp .co.omronsoft.openwnnquot 18. 19. mKeyboardViewKeyboardViewmWnn.getLayoutInflater.inflate idnull 20. mKeyboardView.setOnKeyboardActionListenerthis 21. mCurrentKeyboardnull 22. 23. mMainViewViewGroupparent.getLayoutInflater.inflateR.lay out.keyboard_default_mainnull 24. mSubViewViewGroupparent.getLayoutInflater.inflateR.layo ut.keyboard_default_subnull 25. ifmDisplayModeLANDSCAPEampampmHardKeyboardHidden 26. mMainView.addViewmSubView 27. 28. ifmKeyboardViewnull 29. mMainView.addViewmKeyboardView 30. 31. 32. returnmMainView 33. 34. 其中我们可以看到,程序先通过 layout 文件创建 KeyboardView,然后通过将其封装在一个 mMainView 的 view 变量中。
这里很重要的一段代码是,他会去配置项中读取”skin“这一配置项,并通过该配置项去读取对应的 layout 文件。
这一步是动态变换皮肤的关键,也就是说你可以在配置项中选择不同的皮肤,程序会根据你的选择来生成不同的皮肤。
另外,从 SoftKeyboard 项目中我们知道,KeyboardView 实际上是装着一个Keyboard。
但在这一段代码中只有生成 Keyboard,并未将 Keyboard 封装到KeyboardView 里面,因为当前键盘变量 mCurrentKeyboard 是空的。
这里我们猜测在继承类中会做封装 Keyboard 的操作。
我们看 DefaultSoftKeyboardJAJP.java 的代码:java view plaincopy 1. /seejp.co.omronsoft.openwnn.DefaultSoftKeyboardinitView/ 2. OverridepublicViewinitViewOpenWnnparentintwidthintheig ht 3. 4. Viewviewsuper.initViewparentwidthheight 5. changeKeyboardmKeyboardmCurrentLanguagemDisplayModemCurre ntKeyboardTypemShiftOnmCurrentKeyMode0 6. 7. returnview 8. 这里 changeKeyboard 是父类 DefaultSoftKeyboard 中的函数,其代码为:java view plaincopy 1. / 2. Changethekeyboard. 3. 4. paramkeyboardThenewkeyboard 5. returncodetrueifthekeyboardischangedcode falseifnotchanged. 6. / 7. protectedbooleanchangeKeyboardKeyboardkeyboard 8. 9. ifkeyboardnull 10. returnfalse 11. 12. ifmCurrentKeyboardkeyboard 13. mKeyboardView.setKeyboardkeyboard 14. mKeyboardView.setShiftedmShiftOn0false:true 15. mCurrentKeyboardkeyboard 16. returntrue 17. else 18. mKeyboardView.setShiftedmShiftOn0false:true 19. returnfalse 20. 21. 这里我们可以看到 mKeyboardView.setKeyboardkeyboard这一句,这就验证了我们对 KeyboardView 实际上是装着一个 Keyboard 的猜测。
4、Keyboard 这里的 Keyboard 异常复杂,以至于需要一个 5 维数组来维护。
java view plaincopy 1. / 2. Keyboardsurfaces 3. ltbrgt 4. Keyboardlanguageportrait/landscapekeyboardtypeshiftoff/ onkey‐mode 5. / 6. protectedKeyboardmKeyboard 在 DefaultSoftKeyboard.java 中有许多函数是在做键盘切换的。
另外,这个数组中的每个元素都是一个 Keyboard,他们在 DefaultSoftKeyboardJAJP.java 类中的createKeyboards 函数中创建,其中又调用了 createKeyboardsPortrait 和createKeyboardsLandscape 两个函数来做具体的创建工作。
具体而言是每个键盘对应一个配置文件,这些文件存放在 xml 文件夹下面。
键盘的处理还是比复杂,因为根据不同的输入框,需要显示不同的键盘;同时用户可以选择不同的输入法模式,此时又需要显示不同的键盘。
这一点从onUpdateState 函数,以及 onKey 函数等可以看出。
另外,有些手机不是纯触摸屏的,也就是带有键盘的手机。
对于这些手机是不会显示软键盘的(我猜测),对此需要对硬件盘信息进行设置。
其中setHardKeyboardHidden 函数就是用于做这些事情的。
5、onUpdateState 从函数名我们可以看出这一函数的目的是用于更新状态,主要是用户更新键盘状态(或者是切换键盘)。
从 DefaultSoftKeyboard 类中代码可以看出:java view plaincopy 1. /seejp.co.omronsoft.openwnn.InputViewManageronUpdateState/ 2. publicvoidonUpdateStateOpenWnnparent 3. try 4. ifparent.mComposingText.size10 5. ifmNoInput 6. /whenthemodechangedtoquotnoinputquot/ 7. mNoInputtrue 8. KeyboardnewKeyboardgetKeyboardInputedfalse 9. ifmCurrentKeyboardnewKeyboard 10. changeKeyboardnewKeyboard 11. 12. 13. else 14. ifmNoInput 15. /whenthemodechangedtoquotinputsomecharactersquot/ 16. mNoInputfalse 17. KeyboardnewKeyboardgetKeyboardInputedtrue 18. ifmCurrentKeyboardnewKeyboard 19. changeKeyboardnewKeyboard 20. 21. 22. 23. catchExceptionex 24. 25. 其中 mNoInput 定义为:java view plaincopy 1. / 2. Statusofthecomposingtext 3. ltbrgt 4. codetrueifthereisnocomposingtext. 5. / 6. protectedbooleanmNoInputtrue 这一段代码主要是根据当前的输入状态,来更新键盘的。
程序判断当前输入串(这里指输入时,带有下划线的输入串)是否为空。
若输入串为空,判断 mNoInput是否为有输入串(false),若是,则 mNoInput 改为 true同时键盘改为没有输入串的状态;若输入串不为空,此时若未没有输入串的状态,则要改为有输入串的状态,并相应修改键盘。
而 DefaultSoftKeyboardJAJP 中的这段代码则较为简单:java view plaincopy 1. /seejp.co.omronsoft.openwnn.DefaultSoftKeyboardonUpdateState/ 2. OverridepublicvoidonUpdateStateOpenWnnparent 3. super.onUpdateStateparent 4. setShiftByEditorInfo 5. java view plaincopy 1. / 2. SettheshiftkeystatefromlinkEditorInfo. 3. / 4. privatevoidsetShiftByEditorInfo 5. ifmEnableAutoCapsampampmCurrentKeyModeKEYMODE_JA_HALF_ALPH ABET 6. intshiftgetShiftKeyStatemWnn.getCurrentInputEditorInfo 7. 8. mShiftOnshift 9. changeKeyboardgetShiftChangeKeyboardshift 10. 11. 这一部分代码主要是根据当前输入框的特点相应设置对应的键盘。
6、输入方式(直接上屏或者参与变换) 另外,在使用输入法输入时,通常会有两种方式,一种是参与变换,一种是直接上屏。
参与变换是指,你输入的内容与你需要选择的内容不是一致的,而是通过一系列复杂的变换得到的,比如你输入”kawai“得到”可爱“,就是通过变换而来的;而你在输入字符或者数字时,通常是直接上屏的。
前者需要显示 CandidateView 的,而后者不要。
这一点可能影响的地方包括:不同的输入框(如密码输入框)和不同的输入模式(或者说是输入内容),比如输入数字和字符时,通常就是直接上屏的。
对于这一部分的技术处理,我们从 DefaultSoftKeyboardJAJP 类中的 changeKeyMode 函数可以看出一点端倪。
由于该函数代码有点长,就不展现出来了。
我们看其中几行代码:java view plaincopy 1. caseKEYMODE_JA_HALF_ALPHABET: 2. ifUSE_ENGLISH_PREDICT 3. mInputTypeINPUT_TYPE_TOGGLE 4. modeOpenWnnEvent.Mode.NO_LV1_CONV 5. else 6. mInputTypeINPUT_TYPE_TOGGLE 7. modeOpenWnnEvent.Mode.DIRECT 8. 9. break 如果当前的模式是半角字母输入,则若使用英文预测,则使用的是参与变换的输入方式,若不是用英文预测,则是直接上屏的输入方式。
另外 changeKeyMode 函数的前两行是java view plaincopy 1. inttargetModekeyMode 2. commitText 这是调用了 commitText 函数,该函数的主要功能是上屏,也就是将输入的内容输出到输入框(上屏后的内容没有下划线),在切换输入模式时,通常需要先将当前输入的内容上屏。
另外,需要提一下,在 openwnn 日文输入法中,有一个功能是切换输入模式,如下图 左下角那个按钮,你按一下他会不断变换,从假名输入、英文输入、数字输入循环切换。
其实现方式如下:java view plaincopy 1. /Inputmodetogglecycletable/ 2. privatestaticfinalintJP_MODE_CYCLE_TABLE 3. KEYMODE_JA_FULL_HIRAGANAKEYMODE_JA_HALF_ALPHABETKEYMODE_JA_H ALF_NUMBER 4. java view plaincopy 1. / 2. Changetothenextinputmode 3. / 4. privatevoidnextKeyMode 5. /Searchthecurrentmodeinthetoggletable/ 6. booleanfoundfalse 7. intindex 8. forindex0indexltJP_MODE_CYCLE_TABLE.lengthindex 9. ifJP_MODE_CYCLE_TABLEindexmCurrentKeyMode 10. foundtrue 11. break 12. 13. 14. 15. iffound 16. /Ifthecurrentmodenotexistssetthedefaultmode/ 17. setDefaultKeyboard 18. else 19. /Ifthecurrentmodeexistssetthenextinputmode/ 20. index 21. ifJP_MODE_CYCLE_TABLE.lengthltindex 22. index0 23. 24. changeKeyModeJP_MODE_CYCLE_TABLEindex 25. 26. 这里从程序中就很容易看出是一个循环切换的过程。
同时这个函数,在类似如下场合调用:java view plaincopy 1. /seejp.co.omronsoft.openwnn.DefaultSoftKeyboardonKey/ 2. OverridepublicvoidonKeyintprimaryCodeintkeyCodes 3. 4. switchprimaryCode 5. caseKEYCODE_JP12_TOGGLE_MODE: 6. caseKEYCODE_QWERTY_TOGGLE_MODE: 7. nextKeyMode 8. break7、输入变换7.1 12key 键盘 在 12key 的键盘中,是无法显示所有输入内容的。
于是你按一个键,可能包含多个信息。
比如诺基亚的 12 键键盘: 在这种键盘中,你要输入 c,则要按三下”2“键才可以。
同样的,在日文输入法中,如下键盘(软键盘),你是无法显示所有输入内容的,因此,你可能也像用诺基亚键盘一样,需要按多次才可以输入一个内容。
比如,在如上键盘中,你按”か“键,则按 1 下、2 下、3 下、4 下,5 下,6 下……显示的内容分别是:quotかquot,quotきquot,quotくquot, quotけquot, quotこquot,quotかquot,……。
(注意需要在假名输入模式下) 这里的程序实现是比较巧妙,其中涉及的代码如下:java view plaincopy 1. /Togglecycletableforfull‐widthHIRAGANA/ 2. privatestaticfinalStringJP_FULL_HIRAGANA_CYCLE_TABLE 3. quotu3042quotquotu3044quotquotu3046quotquotu3048quotquotu304aquotquotu3041quotquot u3043quotquotu3045quotquotu3047quotquotu3049quot 4. quotu304bquotquotu304dquotquotu304fquotquotu3051quotquotu3053quot 5. quotu3055quotquotu3057quotquotu3059quotquotu305bquotquotu305dquot 6. quotu305fquotquotu3061quotquotu3064quotquotu3066quotquotu3068quotquotu3063quot 7. quotu306aquotquotu306bquotquotu306cquotquotu306dquotquotu306equot 8. quotu306fquotquotu3072quotquotu3075quotquotu3078quotquotu307bquot 9. quotu307equotquotu307fquotquotu3080quotquotu3081quotquotu3082quot 10. quotu3084quotquotu3086quotquotu3088quotquotu3083quotquotu3085quotquotu3087quot 11. quotu3089quotquotu308aquotquotu308bquotquotu308cquotquotu308dquot 12. quotu308fquotquotu3092quotquotu3093quotquotu308equotquotu30fcquot 13. quotu3001quotquotu3002quotquotuff1fquotquotuff01quotquotu30fbquotquotu3000quot 14. 这是一个循环变换 table,其内容用 utf-8 码显示,对此你可能有点迷糊,但是我把他转为日文,你就懂了:java view plaincopy 1. quotあquotquotいquotquotうquotquotえquotquotおquotquotぁquotquotぃquotquotぅquotquotぇquotquotぉquot 2. quotかquotquotきquotquotくquotquotけquotquotこquot 3. quotさquotquotしquotquotすquotquotせquotquotそquot 4. quotたquotquotちquotquotつquotquotてquotquotとquotquotっquot 5. quotなquotquotにquotquotぬquotquotねquotquotのquot 6. quotはquotquotひquotquotふquotquotへquotquotほquot 7. quotまquotquotみquotquotむquotquotめquotquotもquot 8. quotやquotquotゆquotquotよquotquotゃquotquotゅquotquotょquot 9. quotらquotquotりquotquotるquotquotれquotquotろquot 10. quotわquotquotをquotquotんquotquotゎquotquotーquot 11. quot、quotquot。
quotquot?quotquot!quotquot·quotquot quot 看到了吧,第二行就是我们刚才按”か“键那个例子中显示的内容。
因此其实现我们估计也是很简单的,就是不断的读取这一行的内容。
其程序如下:在Override public void onKeyint primaryCode int keyCodes函数中:java view plaincopy 1. caseKEYCODE_JP12_SHARP: 2. /Processingtoinputbytenkey/ 3. ifmInputTypeINPUT_TYPE_INSTANT 4. /Sendainputcharacterdirectlyifinstantinputtyp eisselected/ 5. commitText 6. mWnn.onEventnewOpenWnnEventOpenWnnEvent.INPUT_CHAR 7. mCurrentInstantTablegetT ableIndexprimaryCode 8. else 9. ifmPrevInputKeyCodeprimaryCode 10. ifmCurrentKeyModeKEYMODE_JA_HALF_ALPHABET 11. ampampprimaryCodeKEYCODE_JP12_SHARP 12. /Committextbysymbolcharacter.wh enalphabetinputmodeisselected/ 13. commitText 14. 15. 16. 17. /Convertthekeycodetothetableindexandsendthe toggleeventwiththetableindex/ 18. StringcycleTablegetCycleTable 19. ifcycleTablenull 20. Log.equotOpenWnnquotquotnotfoundscycletablequot 21. else 22. intindexgetTableIndexprimaryCode 23. mWnn.onEventnewOpenWnnEventOpenWnnEvent.TOGGLE_C HARcycleTableindex 24. mCurrentCycleTablecycleTableindex 25. 26. mPrevInputKeyCodeprimaryCode 27. 28. break 其中 getCycleTable定义如下:java view plaincopy 1. / 2. Getthetoggletableforinputthatisappropriateincurrentmo de. 3. 4. returnThetoggletableforinput 5. / 6. privateStringgetCycleTable 7. StringcycleTablenull 8. switchmCurrentKeyMode 9. caseKEYMODE_JA_FULL_HIRAGANA: 10. cycleTableJP_FULL_HIRAGANA_CYCLE_TABLE 11. break 12. 13. caseKEYMODE_JA_FULL_KATAKANA: 14. cycleTableJP_FULL_KATAKANA_CYCLE_TABLE 15. break 16. 17. caseKEYMODE_JA_FULL_ALPHABET: 18. cycleTableJP_FULL_ALPHABET_CYCLE_TABLE 19. break 20. 21. caseKEYMODE_JA_FULL_NUMBER: 22. caseKEYMODE_JA_HALF_NUMBER: 23. /BecausethesemodesbelongtodirectinputgroupNotog gletableexists/ 24. break 25. 26. caseKEYMODE_JA_HALF_ALPHABET: 27. cycleTableJP_HALF_ALPHABET_CYCLE_TABLE 28. break 29. 30. caseKEYMODE_JA_HALF.
上一篇:
Android Rom制作
下一篇:
法律专业开题报告范文