Android系统应用开发(五)android 输入法类说明

原文地址:http://blog.csdn.net/jianguo_liao19840726/article/details/25370407
源码里面有3套输入法,位置:Z:\myandroid\packages\inputmethods


openwnn是一家日本公司开发的开源输入法框架,涉及中文、日文、韩文。目前已经加入到了Android源码之中。因此你打开一个模拟器时,会发现其中有一个japanese ime的输入法,其服务名为openwnn,这个就是openwnn的日文输入法


latin 虚拟即盘


google是PinyinIME ,后续我们加入了手写,为第三方库支持,13年10月份合并手写和拼音输入法!


现在合并后的为PateoIME



上面截图原因,还有个XmlKeyboardLoader.Java

一、ComposingView

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * View used to show composing string (The Pinyin string for the unselected  
  3.  * syllables and the Chinese string for the selected syllables.)  
  4.  * 拼音字符串View,用于显示输入的拼音  
  5.  */  
  6. public class ComposingView extends View {  

其需要设置的字符通过下面方法传入PateoIME.DecodingInfo decInfo,decInfo中包含了输入的字符,同时进行刷新view

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * Set the composing string to show. If the IME status is  
  3.  * {@link PateoIME.ImeState#STATE_INPUT}, the composing view's status will  
  4.  * be set to {@link ComposingStatus#SHOW_PINYIN}, otherwise the composing  
  5.  * view will set its status to {@link ComposingStatus#SHOW_STRING_LOWERCASE}  
  6.  * or {@link ComposingStatus#EDIT_PINYIN} automatically.  
  7.  * 设置 解码操作对象,然后刷新View  
  8.  */  
  9. public void setDecodingInfo(PateoIME.DecodingInfo decInfo,  
  10.         PateoIME.ImeState imeStatus) {  

其主要绘制在onDraw的drawForPinyin(canvas);方法中,通过canvas.drawText写入

而上面的setDecodingInfo方法主要在InputMethodService的继承的子类中被调用如下:

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. private void updateComposingText(boolean visible) {  
  2.     if (!visible) {  
  3.         mComposingView.setVisibility(View.INVISIBLE);  
  4.     } else {  
  5.         mComposingView.setDecodingInfo(mDecInfo, mImeState);  
  6.         mComposingView.setVisibility(View.VISIBLE);  
  7.     }  
  8.     mComposingView.invalidate();  
  9. }  


二、SoundManager

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * Class used to manage related sound resources.  
  3.  * 按键声音管理类、单例  
  4.  */  
  5. public class SoundManager {  

播放声音前需要注册相应的音频策略,下面为播放声音代码:

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. public void playKeyDown() {  
  2.     if (mAudioManager == null) {  
  3.         updateRingerMode();  
  4.     }  
  5.     if (!mSilentMode) {  
  6.         int sound = AudioManager.FX_KEYPRESS_STANDARD;  
  7.         mAudioManager.playSoundEffect(sound, FX_VOLUME);  
  8.     }  
  9. }  

相应的上面响应按键的方法被调用在SoftKeyboardView类的下面方法中
[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. // If movePress is true, means that this function is called because user  
  2. // moves his finger to this button. If movePress is false, means that this  
  3. // function is called when user just presses this key.  
  4. public SoftKey onKeyPress(int x, int y,  
  5.         SkbContainer.LongPressTimer longPressTimer, boolean movePress) {  
[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. if (!movePress) {  
  2.     tryPlayKeyDown();  
  3.     tryVibrate();  
  4. }  

我们项目中是另外的处理方式,其中特别要注意,在应用监听案件事件的时候需要返回true,不然可能按下键盘键听到两次按键音


三、SoftKeyToggle

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * Class for soft keys which defined in the keyboard xml file. A soft key can be  
  3.  * a basic key or a toggling key.  
  4.  *   
  5.  * @see com.android.inputmethod.pateoime.SoftKey  
  6.  */  
  7. public class SoftKeyToggle extends SoftKey {  

上面主要定义的为切换键,相应的配置<toggle_state>


四、class SoftKey

上面主要为相应的按键


五、SoftKeyboard

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * Class used to represent a soft keyboard definition, including the height, the  
  3.  * background image, the image for high light, the keys, etc.  
  4.  */  
  5. public class SoftKeyboard {  
上面主要是软键盘的定义,包括布局和高宽

此类中有个很关键的函数,就是通过xy坐标值找到相应的临近按键

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. public SoftKey mapToKey(int x, int y) {  

六、SkbTemplate

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * Soft keyboard template used by soft keyboards to share common resources. In  
  3.  * this way, memory cost is reduced.  
  4.  */  
  5. public class SkbTemplate {  

上面主要为:共享公共资源软键盘模板,对应xml资源包下的skb_template.xml、可以根据不同的设备来加载不同的公共资源,其他自由也类似


七、SkbPool

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * Class used to cache previously loaded soft keyboard layouts.  
  3.  */  
  4. public class SkbPool {  

上面说明:用来缓存以前加载的软键盘布局,是一个软键盘缓存池,该类有如下两个变量

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. private Vector<SkbTemplate> mSkbTemplates = new Vector<SkbTemplate>();  
  2. private Vector<SoftKeyboard> mSoftKeyboards = new Vector<SoftKeyboard>();  

即上面看出缓存了布局模板和软键盘两个列表


八、SkbContainer

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * The top container to host soft keyboard view(s).  
  3.  */  
  4. public class SkbContainer extends RelativeLayout implements OnTouchListener {  

上面所说:顶层容器【集装箱】来承载软键盘视图

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * 更新软键盘布局  
  3.  */  
  4. private void updateSkbLayout() {  
  5.     int screenWidth = mEnvironment.getScreenWidth();  
  6.     int keyHeight = mEnvironment.getKeyHeight();  
  7.     int skbHeight = mEnvironment.getSkbHeight();  
  8.   
  9.     Resources r = mContext.getResources();  
  10.     if (null == mSkbFlipper) {  
  11.         mSkbFlipper = (ViewFlipper) findViewById(R.id.alpha_floatable);  
  12.     }  
  13.     mMajorView = (SoftKeyboardView) mSkbFlipper.getChildAt(0);  
  14.   
  15.     SoftKeyboard majorSkb = null;  
  16.     SkbPool skbPool = SkbPool.getInstance();  
  17.   
  18.     switch (mSkbLayout) {  
  19.     case R.xml.skb_qwerty:  
  20.         majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty,  
  21.                 R.xml.skb_qwerty, screenWidth, skbHeight, mContext);  
  22.         break;  
  23.   
  24.     case R.xml.skb_sym1:  
  25.         majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym1, R.xml.skb_sym1,  
  26.                 screenWidth, skbHeight, mContext);  
  27.         break;  
  28.   
  29.     case R.xml.skb_sym2:  
  30.         majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym2, R.xml.skb_sym2,  
  31.                 screenWidth, skbHeight, mContext);  
  32.         break;  
  33.   
  34.     case R.xml.skb_smiley:  
  35.         majorSkb = skbPool.getSoftKeyboard(R.xml.skb_smiley,  
  36.                 R.xml.skb_smiley, screenWidth, skbHeight, mContext);  
  37.         break;  
  38.   
  39.     case R.xml.skb_phone:  
  40.         majorSkb = skbPool.getSoftKeyboard(R.xml.skb_phone,  
  41.                 R.xml.skb_phone, screenWidth, skbHeight, mContext);  
  42.         break;  
  43.     default:  
  44.     }  
  45.   
  46.     if (null == majorSkb || !mMajorView.setSoftKeyboard(majorSkb)) {  
  47.         return;  
  48.     }  
  49.     mMajorView.setBalloonHint(mBalloonOnKey, mBalloonPopup, false);  
  50.     mMajorView.invalidate();  
  51. }  

[html]  view plain   copy
  在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. public boolean onTouchEvent(MotionEvent event) {  
  3.     super.onTouchEvent(event);  
  4.   
  5.   
  6.     if (mSkbFlipper.isFlipping()) {  
  7.         resetKeyPress(0);  
  8.         return true;  
  9.     }  
  10.   
  11.   
  12.     int x = (int) event.getX();  
  13.     int y = (int) event.getY();  
  14.     // Bias correction  
  15.     y = y + mYBiasCorrection;  
  16.   
  17.   
  18.     // Ignore short-distance movement event to get better performance.  
  19.     if (event.getAction() == MotionEvent.ACTION_MOVE) {  
  20.         if (Math.abs(x - mXLast) <= MOVE_TOLERANCE  
  21.                 && Math.abs(y - mYLast) <= MOVE_TOLERANCE) {  
  22.             return true;  
  23.         }  
  24.     }  
  25.   
  26.   
  27.     mXLast = x;  
  28.     mYLast = y;  
  29.   
  30.   
  31.     if (!mPopupSkbShow) {  
  32.         // mGestureDetector的监听器在输入法服务PinyinIME中。  
  33.         if (mGestureDetector.onTouchEvent(event)) {  
  34.             resetKeyPress(0);  
  35.             mDiscardEvent = true;  
  36.             return true;  
  37.         }  
  38.     }  
  39.   
  40.   
  41.     switch (event.getAction()) {  
  42.     case MotionEvent.ACTION_DOWN:  
  43.         resetKeyPress(0);  
  44.   
  45.   
  46.         mWaitForTouchUp = true;  
  47.         mDiscardEvent = false;  
  48.   
  49.   
  50.         mSkv = null;  
  51.         mSoftKeyDown = null;  
  52.         mSkv = inKeyboardView(x, y, mSkvPosInContainer);  
  53.         if (null != mSkv) {  
  54.             mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y  
  55.                     - mSkvPosInContainer[1], mLongPressTimer, false);  
  56.         }  
  57.         break;  
  58.   
  59.   
  60.     case MotionEvent.ACTION_MOVE:  
  61.         if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {  
  62.             break;  
  63.         }  
  64.         if (mDiscardEvent) {  
  65.             resetKeyPress(0);  
  66.             break;  
  67.         }  
  68.   
  69.   
  70.         if (mPopupSkbShow && mPopupSkbNoResponse) {  
  71.             break;  
  72.         }  
  73.   
  74.   
  75.         SoftKeyboardView skv = inKeyboardView(x, y, mSkvPosInContainer);  
  76.         if (null != skv) {  
  77.             if (skv != mSkv) {  
  78.                 mSkv = skv;  
  79.                 mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y  
  80.                         - mSkvPosInContainer[1], mLongPressTimer, true);  
  81.             } else if (null != skv) {  
  82.                 if (null != mSkv) {  
  83.                     mSoftKeyDown = mSkv.onKeyMove(  
  84.                             x - mSkvPosInContainer[0], y  
  85.                                     - mSkvPosInContainer[1]);  
  86.                     if (null == mSoftKeyDown) {  
  87.                         mDiscardEvent = true;  
  88.                     }  
  89.                 }  
  90.             }  
  91.         }  
  92.         break;  
  93.   
  94.   
  95.     case MotionEvent.ACTION_UP:  
  96.         if (mDiscardEvent) {  
  97.             resetKeyPress(0);  
  98.             break;  
  99.         }  
  100.   
  101.   
  102.         mWaitForTouchUp = false;  
  103.   
  104.   
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Android 输入法开发是指为Android系统开发一款输入法应用程序的过程。输入法是一种用于输入文字的工具,通过输入法,用户可以在Android设备上输入各种语言的文字。 Android 输入法开发需要掌握一定的编程知识和技巧。首先,开发者需要了解Android系统的架构和输入法的工作原理。其次,需要使用Java等编程语言来编写输入法的代码。开发者还需要使用Android Studio等开发工具来调试和测试输入法的功能。 在Android 输入法开发过程中,需要考虑以下几个关键点。首先,输入法需要正确地处理用户输入的字符,并将其显示在屏幕上。其次,输入法需要提供联想和自动完成的功能,以帮助用户更快地输入文字。此外,输入法还需要支持多种输入方式,例如手写输入、语音输入等。 同时,开发者还应该关注输入法的用户体验。输入法应该具有良好的界面设计和交互方式,方便用户使用。此外,输入法还应该具备一定的智能化功能,例如根据用户的输入习惯进行个性化设置,提供更准确的输入建议等。 最后,输入法开发完成后,开发者还需要将其发布到应用商店供用户下载和使用。在发布前,需要对输入法进行充分的测试和迭代,确保其稳定性和功能完善性。 总的来说,Android 输入法开发是一个复杂而有挑战的过程,但随着技术的不断发展和改进,越来越多的开发者参与到输入法开发中,推动了输入法的创新和提升。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值