【Java精品源码栏目提醒】:文章导读:在新的一年中,各位网友都进入紧张的学习或是工作阶段。
网学会员整理了Java精品源码-android输入法01:SoftKeyboard源码解析03 - 网络与通信的相关内容供大家参考,祝大家在新的一年里工作和学习顺利!
android 输入法 01:SoftKeyboard
源码解析 034、SoftKeyboardjava view plaincopy 1. / 2. Exampleofwritinganinputmethodforasoftkeyboard.Thiscodei s 3. focusedonsimplicityovercompletenesssoitshouldinnowaybec onsidered 4. tobeacompletesoftkeyboardimplementation.Itspurposeistopr ovide 5. abasicexampleforhowyouwouldgetstartedwritinganinputmetho dto 6. befleshedoutasappropriate. 7. / 8. publicclassSoftKeyboardextendsInputMethodService 9. implementsKeyboardView.OnKeyboardActionListener 10. staticfinalbooleanDEBUGfalse 11. 12. / 13. Thisbooleanindicatestheoptionalexamplecodeforperforming 14. processingofhardkeysinadditiontoregulartextgeneration 15. fromon‐ screeninteraction.Itwouldbeusedforinputmethodsthat 16. performlanguagetranslationssuchasconvertingtextenteredo n 17. aQWERTYkeyboardtoChinesebutmaynotbeusedforinputmet hods 18. thatareprimarilyintendedtobeusedforon‐ screentextentry. 19. / 20. //是否在用硬键盘,这里默认的是总可以使用费柴变量 21. staticfinalbooleanPROCESS_HARD_KEYStrue 22. 23. //键盘 view 对象但不是自己定义的类 latinkeyboardview.... 24. privateKeyboardViewmInputView 25. //候选栏对象 26. privateCandidateViewmCandidateView 27. //候选串之串 28. privateCompletionInfomCompletions 29. 30. privateStringBuildermComposingnewStringBuilder 31. //这东西是决定能不能有候选条 32. privatebooleanmPredictionOn 33. //决定 auto 是否需要显示在候选栏 34. privatebooleanmCompletionOn 35.36. privateintmLastDisplayWidth37. privatebooleanmCapsLock38. privatelongmLastShiftTime39. //matakey 的按下状态,猜测是每种组合对应一个此值?40. privatelongmMetaState41.42. privateLatinKeyboardmSymbolsKeyboard43. privateLatinKeyboardmSymbolsShiftedKeyboard44. privateLatinKeyboardmQwertyKeyboard45.46. //当前键盘47. privateLatinKeyboardmCurKeyboard48.49. //默认的使得输入中断的字符50. privateStringmWordSeparators51.52. /53. Maininitializationoftheinputmethodcomponent.Besuretoc all54. tosuperclass.55. /56. OverridepublicvoidonCreate57. super.onCreate58. //对 resource 这个东西有了一些了解:getResources 是 contextWrapper 类 的函数,contextWrapper 而是 inputmethodservice59. //的间接基类60. mWordSeparatorsgetResources.getStringR.string.word_separa tors61. Log.iquotmytestquotquotSoftKeyboard_onCreatequot62. 63.64. /65. ThisisthepointwhereyoucandoallofyourUIinitialization .It66. iscalledaftercreationandanyconfigurationchange.67. /68. OverridepublicvoidonInitializeInterface69. Log.iquotmytestquotquotSoftKeyboard_onInitializeInterfacequot70. //这只加载键盘,类似于 findViewById,离真正生成界面还早71. ifmQwertyKeyboardnull72. //Configurationchangescanhappenafterthekeyboardgets recreated73. //soweneedtobeabletore‐ buildthekeyboardsiftheavailable74. //spacehaschanged.75. //可用的,最大屏幕宽度,好像也没什么用76. intdisplayWidthgetMaxWidth77. ifdisplayWidthmLastDisplayWidthreturn78. //难道就是为了记录最大宽度于 mLastDisplayWidth?79. mLastDisplayWidthdisplayWidth80. 81. mQwertyKeyboardnewLatinKeyboardthisR.xml.qwerty82. mSymbolsKeyboardnewLatinKeyboardthisR.xml.symbols83. mSymbolsShiftedKeyboardnewLatinKeyboardthisR.xml.symbols _shift84. 85.86. /87. Calledbytheframeworkwhenyourviewforcreatinginputneeds to88. begenerated.Thiswillbecalledthefirsttimeyourinputmet hod89. isdisplayedandeverytimeitneedstobere‐ createdsuchasdueto90. aconfigurationchange.91. /92. OverridepublicViewonCreateInputView93. Log.iquotmytestquotquotSoftKeyboard_onCreateInputViewquot94. mInputViewKeyboardViewgetLayoutInflater.inflate95. R.layout.inputnull96. //上边的函数 findViewById 对于 keyboardView 是不能用的97. //只对 TextView 等可以用98. mInputView.setOnKeyboardActionListenerthis99. mInputView.setKeyboardmQwertyKeyboard100. //通过这个 return自己定义的 keyboardview 类对象就与这个类绑定 了101. returnmInputView102. 103.104. /105. Calledbytheframeworkwhenyourviewforshowingcandidates needsto106. begeneratedlikelinkonCreateInputView.107. /108. OverridepublicViewonCreateCandidatesView109. Log.iquotmytestquotquotSoftKeyboard_onCreateCandidatesViewquot110. mCandidateViewnewCandidateViewthis111. //为什么参数是 this因为 activityinputmethodservice这都是 context 的派生类112. mCandidateView.setServicethis//在 CandidateView 类里面对这 个类的描述中,参数就是个113. returnmCandidateView//这一步很重要,后面的 setCandidatesViewShownfalse就是个返回的结果造成的?114. 115.116. /117. Thisisthemainpointwherewedoourinitializationofthe inputmethod118. tobeginoperatingonanapplication.Atthispointwehave been119. boundtotheclientandarenowreceivingallofthedetaile dinformation120. aboutthetargetofouredits.121. /122. OverridepublicvoidonStartInputEditorInfoattributeboolean restarting123. super.onStartInputattributerestarting124. Log.iquotmytestquotquotSoftKeyboard_onStartInputquot125. //Resetourstate.Wewanttodothisevenifrestarting because126. //theunderlyingstateofthetexteditorcouldhavechange dinanyway.127. //一个 StringBuilder前面定义的128. mComposing.setLength0129. updateCandidates//可知此处的 candidateview 注定还不显示130.131. ifrestarting132. //Clearshiftstates.133. mMetaState0134. 135.136. mPredictionOnfalse//猜测:是否需要显示候选词条证实确实如 此137. mCompletionOnfalse//允许 auto 的内容显示在后选栏中138. mCompletionsnull139.140. //Wearenowgoingtoinitializeourstatebasedonthetyp eof141. //textbeingedited.142. //一个靠谱的猜测:inputtype 的给定值里面有那么几个掩码,但是从参数 传来的具体 inputtype 值里面包含了所有的信息,不同的掩码能够得出不同的信息143. //例如 TYPE_MASK_CLASS 就能得出下面四种,这四种属于同一类期望信息, 这个信息叫做 CLASS下面一个掩码 TYPE_MASK_VARIATION 按位与出来的是一类144. //叫做 VARIATION 的信息145. switchattribute.inputTypeampEditorInfo.TYPE_MASK_CLASS146. caseEditorInfo.TYPE_CLASS_NUMBER:147. caseEditorInfo.TYPE_CLASS_DATETIME:148. //Numbersanddatesdefaulttothesymbolskeyboard with149. //noextrafeatures.150. mCurKeyboardmSymbolsKeyboard151. break152.153. caseEditorInfo.TYPE_CLASS_PHONE:154. //Phoneswillalsodefaulttothesymbolskeyboard though155. //oftenyouwillwanttohaveadedicatedphonekey board.156. mCurKeyboardmSymbolsKeyboard157. break158.159. caseEditorInfo.TYPE_CLASS_TEXT:160. //Thisisgeneraltextediting.Wewilldefaultto the161. //normalalphabetickeyboardandassumethatwesh ould162. //bedoingpredictivetextshowingcandidatesast he163. //usertypes.164. mCurKeyboardmQwertyKeyboard165. mPredictionOntrue166.167. //Wenowlookforafewspecialvariationsoftext thatwill168. //modifyourbehavior.169. intvariationattribute.inputTypeampEditorInfo.TY PE_MASK_VARIATION170. ifvariationEditorInfo.TYPE_TEXT_VARIATION_PASS WORD171. variationEditorInfo.TYPE_TEXT_VARIATION_ VISIBLE_PASSWORD172. //Donotdisplaypredictions/whattheuseris typing173. //whentheyareenteringapassword.174. mPredictionOnfalse//密码框的输入是不需要候选 词条的175. 176.177. ifvariationEditorInfo.TYPE_TEXT_VARIATION_EMAI L_ADDRESS178. variationEditorInfo.TYPE_TEXT_VARIATI ON_URI179. variationEditorInfo.TYPE_TEXT_VARIATI ON_FILTER180. //Ourpredictionsarenotusefulfore‐ mailaddresses181. //orURIs.182. mPredictionOnfalse//如果是网站或者是邮箱地 址,不用候选词条183. 184.185. ifattribute.inputTypeampEditorInfo.TYPE_TEXT_FLAG_A UTO_COMPLETE0186. //开始界面的那个输入框,就是自动生成的187. //Ifthisisanauto‐ completetextviewthenourpredictions188. //willnotbeshownandinsteadwewillallowt heeditor189. //tosupplytheirown.Weonlyshowtheeditor s190. //candidateswheninfullscreenmodeotherwise relying191. //ownitdisplayingitsownUI.192. mPredictionOnfalse193. //经过测试,当输入法处在全屏模式的时候,原本 auto 的候 选词会显示在输入法的候选栏中194. //这是 mCompletiOn 的作用,这个值初始化设为 false.195. //如果把这里的两个值都设置为 true 则可以发现再输入任意 auto 的时候都会在候选栏中显示 auto 的词语196. //所以,变量 mCompletionOn 的后续作用需要监视197.198. //这两行做后续测试:真值: falseisFullscreenMode199. mCompletionOnisFullscreenMode200. 201.202. //Wealsowanttolookatthecurrentstateofthe editor203. //todecidewhetherouralphabetickeyboardshould startout204. //shifted.205. updateShiftKeyStateattribute206. break207.208. default:209. //Forallunknowninputtypesdefaulttothealpha betic210. //keyboardwithnospecialfeatures.211. mCurKeyboardmQwertyKeyboard212. updateShiftKeyStateattribute//决定是否需要初始大写 状态213. 214.215. //Updatethelabelontheenterkeydependingonwhatthe application216. //saysitwilldo.217. mCurKeyboard.setImeOptionsgetResourcesattribute.imeOpti ons//根据输入目标设置回车键218. 219.220. /221. Thisiscalledwhentheuserisdoneeditingafield.Wecan use222. thistoresetourstate.223. /224. OverridepublicvoidonFinishInput225. super.onFinishInput226. Log.iquotmytestquotquotSoftKeyboard_onFinishInputquot227. //经测试,终于发现,start 与 finish在输入框切换的时候,平时这俩 结束函数并不调用,或许输入框只是隐藏。
228.229. //测试语句mInputViewnull230. //Clearcurrentcomposingtextandcandidates.231. mComposing.setLength0232. updateCandidates233.234. //Weonlyhidethecandidateswindowwhenfinishinginputo n235. //aparticulareditortoavoidpoppingtheunderlyingappl ication236. //upanddowniftheuserisenteringtextintothebottom of237. //itswindow.238. setCandidatesViewShownfalse//默认的就是不可见的239.240. mCurKeyboardmQwertyKeyboard241. ifmInputViewnull242. mInputView.closing//据分析,关闭输入界面和收起输入界面 还不是一回事?243. 244. 245.246. OverridepublicvoidonStartInputViewEditorInfoattributeboo leanrestarting247. super.onStartInputViewattributerestarting248. //如果没有这个函数的作用,在切换输入目标的时候不会发生键盘的变化249. //而且经过测试,这个函数执行的时间是开始输入的时候250. //Applytheselectedkeyboardtotheinputview.251. Log.iquotmytestquotquotSoftKeyboard_onStartInputViewquot252. mInputView.setKeyboardmCurKeyboard253. //这个是转换键盘的关键254. //mInputView 是自己定义的一个键盘255. mInputView.closing//这个语句能让整个需要输入的目标关闭?到 底是干什么用的??疑问?256. 257.258. /259. Dealwiththeeditorreportingmovementofitscursor.260. /261. OverridepublicvoidonUpdateSelectionintoldSelStartintold SelEnd262. intnewSelStartintnewSelEnd263. intcandidatesStartintcandidatesEnd264. //光标!265. super.onUpdateSelectionoldSelStartoldSelEndnewSelStart newSelEnd266. candidatesStartcandidatesEnd267. Log.iquotmytestquotquotSoftKeyboard_onUpdateSelectionquot268. //Ifthecurrentselectioninthetextviewchangeswesho uld269. //clearwhatevercandidatetextwehave.270. //当输入框向输入法报告用户移动了光标时调用。
,当用户移动输入框中的光 标的时候,它就默认的表示本次输入完成了,271. //然后将候选词以及正在输入的文本复位,并且向编辑器报告输入法已经完成 了一个输入。
272. //四个整形都是坐标?273. ifmComposing.lengthgt0ampampnewSelStartcandidatesEnd274. newSelEndcandidatesEnd275. mComposing.setLength0//这才是候选栏置空的精义所在276. updateCandidates//候选栏置空277. InputConnectionicgetCurrentInputConnection//这个 语句和下面 if 里面那个,决定了结束输入的全过程278. ificnull279. ic.finishComposingText//这个语句的作用是,让输入目 标内的下划线去掉,完成一次编辑280. 281. 282. 283.284. /285. Thistellsusaboutcompletionsthattheeditorhasdetermine dbased286. onthecurrenttextinit.Wewanttousethisinfullscreen mode287. toshowthecompletionsourselfsincetheeditorcannotbe seen288. inthatsituation.289. /290. OverridepublicvoidonDisplayCompletionsCompletionInfocomp letions291. //当需要在候选栏里面显示 auto 的内容292. //此函数作用,猜测:当全屏幕模式的时候,mCompletionOn 置 true可 以通过候选栏来显示 auto293. Log.iquotmytestquotquotSoftKeyboard_onDisplayCompletionsquot294. ifmCompletionOn//必须这个变量允许295. mCompletionscompletions//赋值给本来里面专门记录候选值 的变量296. ifcompletionsnull297. setSuggestionsnullfalsefalse//如果没有候选词, 就这样处置298. return299. 300.301. ListltStringgtstringListnewArrayListltStringgt302. forinti0iltcompletionsnullcompletions.lengt h:0i303. CompletionInfocicompletionsi304. ifcinullstringList.addci.getText.toString 305. 306. setSuggestionsstringListtruetrue307. 308. 309.310. /311. Thistranslatesincominghardkeyeventsintoeditoperation sonan312. InputConnection.Itisonlyneededwhenusingthe313. PROCESS_HARD_KEYSoption.314. /315. privatebooleantranslateKeyDownintkeyCodeKeyEventevent316. //这个函数在 OnKeyDown 中用到了317. //这个是当组合键时候用,shiftA 或者别的 AltA 之类318. Log.iquotmytestquotquotSoftKeyboard_translateKeyDownquot319. mMetaStateMetaKeyKeyListener.handleKeyDownmMetaState320. keyCodeevent321. //处理 matakey 的按下,猜测:每一个 long 型的 mMetaState 值都代表着 一个 meta 键组合值。
8 成是对的322. intcevent.getUnicodeCharMetaKeyKeyListener.getMetaState mMetaState//如果没这套组合键,就返回 0323. //这又是在干什么?猜测:每一个 mMetaState 值,对应着一个 unicode 值,这一步就是为了得到它,此猜测正确324. //重置这个元状态。
当取得了 C 值之后,完全可以重置元状态了,后面的语句 不会出现任何问题。
325. //上面这三行有点疑问326. mMetaStateMetaKeyKeyListener.adjustMetaAfterKeypressmMet aState327.328. //后边这函数是 inputmethodservice 自己的,获得当前的链接329. InputConnectionicgetCurrentInputConnection330. ifc0icnull331. returnfalse332. 333.334. //一个 deadtrue 意味着是一个有定义的组合键335. booleandeadfalse336.337. //看看 c 所昭示的这个键能不能被允许组合键338. ifcampKeyCharacterMap.COMBINING_ACCENT0339. //定义下来看能否使用这个组合键340. deadtrue341. //这样就得到了真正的码值342. ccampKeyCharacterMap.COMBINING_ACCENT_MASK343. 344.345. //这是处理“编辑中最后字符越变”的情况346. ifmComposing.lengthgt0347. characcentmComposing.charAtmComposing.length‐ 1//返回正在编辑的字串的最后一个字符348. //这种情况下最后是返回了新的阿斯课码。
composed 最终还是要还给 c.作为 onKey 的参数。
349. intcomposedKeyEvent.getDeadCharaccentc350.351. ifcomposed0352. ccomposed353. mComposing.setLengthmComposing.length‐1//要把 最后一个字符去掉,才能够在下一步中越变成为新的字符354. 355. 356.357. onKeycnull//强制输入 C这样就实现了组合键的功效358.359. returntrue360. 361.362. /363. Usethistomonitorkeyeventsbeingdeliveredtotheapplica tion.364. Wegetfirstcrackatthemandcaneitherresumethemorlet them365. continuetotheapp.366. /367. OverridepublicbooleanonKeyDownintkeyCodeKeyEventevent 368. Log.iquotmytestquotquotSoftKeyboard_onKeyDownquot369. //这是重载了基类的经测试确定,只有在硬件盘被敲击时候才调用,除了 那个键本身的功效,还有这里定义的这些370. //是对输入法的影响371. switchkeyCode372. caseKeyEvent.KEYCODE_BACK://这就是那个破箭头,扭曲的373. //TheInputMethodServicealreadytakescareofthe back374. //keyforustodismisstheinputmethodifitis shown.375. //Howeverourkeyboardcouldbeshowingapop‐ upwindow376. //thatbackshoulddismisssowefirstallowitto dothat.377. //mInputView 类是自己定义的 keyBoardView 类378. ifevent.getRepeatCount0ampampmInputViewnul l379. ifmInputView.handleBack//通过弯钩键来关闭 键盘的元凶在这里380. //这函数干吗呢?猜测:如果成功地荡掉了键盘,就返 回真381. returntrue382. 383. 384. break385.386. caseKeyEvent.KEYCODE_DEL:387. //Specialhandlingofthedeletekey:ifwecurrent lyare388. //composingtextfortheuserwewanttomodifyth atinstead389. //oflettheapplicationtothedeleteitself.390. ifmComposing.lengthgt0391. onKeyKeyboard.KEYCODE_DELETEnull//所以, onkey 定义中的事情才是软键盘的事件392. re.