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月份合并手写和拼音输入法!


android 输入法类说明_第1张图片


现在合并后的为PateoIME

android 输入法类说明_第2张图片

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


一、ComposingView

[html]  view plain  copy
 
  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
 
  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
 
  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
 
  1. /**  
  2.  * Class used to manage related sound resources.  
  3.  * 按键声音管理类、单例  
  4.  */  
  5. public class SoundManager {  

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

[html]  view plain  copy
 
  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
 
  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
 
  1. if (!movePress) {  
  2.     tryPlayKeyDown();  
  3.     tryVibrate();  
  4. }  

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


三、SoftKeyToggle

[html]  view plain  copy
 
  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 {  

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


四、class SoftKey

上面主要为相应的按键


五、SoftKeyboard

[html]  view plain  copy
 
  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
 
  1. public SoftKey mapToKey(int x, int y) {  

六、SkbTemplate

[html]  view plain  copy
 
  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
 
  1. /**  
  2.  * Class used to cache previously loaded soft keyboard layouts.  
  3.  */  
  4. public class SkbPool {  

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

[html]  view plain  copy
 
  1. private Vector<SkbTemplate> mSkbTemplates = new Vector<SkbTemplate>();  
  2. private Vector<SoftKeyboard> mSoftKeyboards = new Vector<SoftKeyboard>();  

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


八、SkbContainer

[html]  view plain  copy
 
  1. /**  
  2.  * The top container to host soft keyboard view(s).  
  3.  */  
  4. public class SkbContainer extends RelativeLayout implements OnTouchListener {  

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

[html]  view plain  copy
 
  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
 
  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.   
  105.         // The view which got the {@link MotionEvent#ACTION_DOWN} event is  
  106.         // always used to handle this event.  
  107.         if (null != mSkv) {  
  108.             mSkv.onKeyRelease(x - mSkvPosInContainer[0], y  
  109.                     - mSkvPosInContainer[1]);  
  110.         }  
  111.   
  112.   
  113.         if (!mPopupSkbShow || !mPopupSkbNoResponse) {  
  114.             responseKeyEvent(mSoftKeyDown);  
  115.         }  
  116.   
  117.   
  118.         if (mSkv == mPopupSkbView && !mPopupSkbNoResponse) {  
  119.             dismissPopupSkb();  
  120.         }  
  121.         mPopupSkbNoResponse = false;  
  122.         break;  
  123.   
  124.   
  125.     case MotionEvent.ACTION_CANCEL:  
  126.         break;  
  127.     }  
  128.   
  129.   
  130.     if (null == mSkv) {  
  131.         return false;  
  132.     }  
  133.   
  134.   
  135.     return true;  
  136. }  


九、Settings

[html]  view plain  copy
 
  1. /**  
  2.  * Class used to maintain settings.  
  3.  */  
  4. public class Settings {  

上面所说,为设置类,单例、主要设置如下:震动、声音、预报

[html]  view plain  copy
 
  1. public static void writeBack() {  
  2.     Editor editor = mSharedPref.edit();  
  3.     editor.putBoolean(ANDPY_CONFS_VIBRATE_KEY, mVibrate);  
  4.     editor.putBoolean(ANDPY_CONFS_KEYSOUND_KEY, mKeySound);  
  5.     editor.putBoolean(ANDPY_CONFS_PREDICTION_KEY, mPrediction);  
  6.     editor.commit();  
  7. }  


十、SettingsActivity

[html]  view plain  copy
 
  1. /**  
  2.  * Setting activity of Pinyin IME.  
  3.  */  
  4. public class SettingsActivity  

上面意思设置的Acitivty、一般项目中会有改动,可以放入专门的设置应用中,这个设置信息量大,可以不用单独为输入法搞个设置Activity


十一、BalloonHint

[html]  view plain  copy
 
  1. /**  
  2.  * Subclass of PopupWindow used as the feedback when user presses on a soft key  
  3.  * or a candidate.  
  4.  */  
  5. public class BalloonHint extends PopupWindow {  

从上面注释来看主要是:用户按下一个软键或候选人时冒出的气泡


十二、HandWriteView

[html]  view plain  copy
 
  1.   public void TouchEvent(MotionEvent event) {  
  2.     float x = event.getX(0);  
  3.     float y = event.getY(0);  
  4.     switch (event.getAction()) {  
  5.         case MotionEvent.ACTION_DOWN:  
  6.             touch_start(x, y);  
  7.             break;  
  8.         case MotionEvent.ACTION_MOVE:  
  9.             touch_move(x, y);  
  10.             break;  
  11.         case MotionEvent.ACTION_UP:  
  12.         
  13.           mhandler.postDelayed(Recognition, timer);  
  14.           break;  
  15.     }  
  16. }  
上面为手写输入的view,主要拿到move的xy值,然后把其上一个xy值作为起始值,后续的作为停止值,再这样的逻辑下去,即可以划直线连接相应的点在理论逻辑上不会断点

[html]  view plain  copy
 
  1. mCanvas.drawLine(mX, mY, x, y, mPaint);  
针对刷新view,则建议invalidate根据实际的cpu占用来优化


十三、HandWriteDecoder

[html]  view plain  copy
 
  1. public char[] RecognitionResult(short p[],int len){  
  2.     native char[] getResult(short point[],int len)  
  3. }  

输入法手写识别的结果返回处理类,主要调用了返回结果的native方法,传进去xy的坐标值数组,返回字符串的char数组


十四、KeyMapDream

[html]  view plain  copy
 
  1. /**  
  2.  * Class used to map the symbols on Dream's hardware keyboard to corresponding  
  3.  * Chinese full-width symbols.  
  4.  */  
  5. public class KeyMapDream {  

上面类的说明:硬件键盘上的符号映射到相应的中国全角符号


十五、Environment


[html]  view plain  copy
 
  1. /**  
  2.  * Global environment configurations for showing soft keyboard and candidate  
  3.  * view. All original dimension values are defined in float, and the real size  
  4.  * is calculated from the float values of and screen size. In this way, this  
  5.  * input method can work even when screen size is changed.  
  6.  * 该类保存布局的一些尺寸。比如:屏幕的宽度、屏幕的高度  
  7.  * 、按键的高度、候选词区域的高度、按键气泡宽度比按键宽度大的差值、按键气泡高度比按键高度大的差值、正常按键中文本的大小  
  8.  * 、功能按键中文本的大小、正常按键气泡中文本的大小、功能按键气泡中文本的大小。  
  9.  */  
  10. public class Environment {  
  11.     /**  
  12.      * The key height for portrait mode. It is relative to the screen height.  
  13.      * 竖屏按键高度,值是相对于屏幕高度。  
  14.      */  
  15.     private static final float KEY_HEIGHT_RATIO_PORTRAIT = 0.105f;  
  16.   
  17.     /**  
  18.      * The key height for landscape mode. It is relative to the screen height.  
  19.      * 横屏按键高度,值是相对于屏幕高度。  
  20.      */  
  21.     private static final float KEY_HEIGHT_RATIO_LANDSCAPE = 0.147f;  
  22.   
  23.     /**  
  24.      * The height of the candidates area for portrait mode. It is relative to  
  25.      * screen height. 竖屏候选词区域的高度,值是相对于屏幕高度。  
  26.      */  
  27.     private static final float CANDIDATES_AREA_HEIGHT_RATIO_PORTRAIT = 0.084f;  
  28.   
  29.     /**  
  30.      * The height of the candidates area for portrait mode. It is relative to  
  31.      * screen height. 横屏候选词区域高度,值是相对于屏幕高度。  
  32.      */  
  33.     private static final float CANDIDATES_AREA_HEIGHT_RATIO_LANDSCAPE = 0.125f;  
  34.   
  35.     /**  
  36.      * How much should the balloon width be larger than width of the real key.  
  37.      * It is relative to the smaller one of screen width and height.  
  38.      * 猜测:点击软键盘按钮时弹出来的气泡大于按键的宽度的差值,值是相对于屏幕高度和宽度较小的那一个。  
  39.      */  
  40.     private static final float KEY_BALLOON_WIDTH_PLUS_RATIO = 0.08f;  
  41.   
  42.     /**  
  43.      * How much should the balloon height be larger than that of the real key.  
  44.      * It is relative to the smaller one of screen width and height.  
  45.      * 猜测:点击软键盘按钮时弹出来的气泡大于按键的高度的差值,值是相对于屏幕高度和宽度较小的那一个。  
  46.      */  
  47.     private static final float KEY_BALLOON_HEIGHT_PLUS_RATIO = 0.07f;  
  48.   
  49.     /**  
  50.      * The text size for normal keys. It is relative to the smaller one of  
  51.      * screen width and height. 正常按键的文本的大小,值是相对于屏幕高度和宽度较小的那一个。  
  52.      */  
  53.     private static final float NORMAL_KEY_TEXT_SIZE_RATIO = 0.075f;  
  54.   
  55.     /**  
  56.      * The text size for function keys. It is relative to the smaller one of  
  57.      * screen width and height. 功能按键的文本的大小,值是相对于屏幕高度和宽度较小的那一个。  
  58.      */  
  59.     private static final float FUNCTION_KEY_TEXT_SIZE_RATIO = 0.055f;  
  60.   
  61.     /**  
  62.      * The text size balloons of normal keys. It is relative to the smaller one  
  63.      * of screen width and height. 正常按键弹出的气泡的文本的大小,值是相对于屏幕高度和宽度较小的那一个。  
  64.      */  
  65.     private static final float NORMAL_BALLOON_TEXT_SIZE_RATIO = 0.14f;  
  66.   
  67.     /**  
  68.      * The text size balloons of function keys. It is relative to the smaller  
  69.      * one of screen width and height. 功能按键弹出的气泡的文本的大小,值是相对于屏幕高度和宽度较小的那一个。  
  70.      */  
  71.     private static final float FUNCTION_BALLOON_TEXT_SIZE_RATIO = 0.085f;  
  72.   
  73.     /**  
  74.      * The configurations are managed in a singleton. 该类的实例,该类采用设计模式的单例模式。  
  75.      */  
  76.     private static Environment mInstance;  
  77.   
  78.     private int mScreenWidth; // 屏幕的宽度  
  79.     private int mScreenHeight; // 屏幕的高度  
  80.     private int mKeyHeight; // 按键的高度  
  81.     private int mCandidatesAreaHeight; // 候选词区域的高度  
  82.     private int mKeyBalloonWidthPlus; // 按键气泡宽度比按键宽度大的差值  
  83.     private int mKeyBalloonHeightPlus; // 按键气泡高度比按键高度大的差值  
  84.     private int mNormalKeyTextSize; // 正常按键中文本的大小  
  85.     private int mFunctionKeyTextSize; // 功能按键中文本的大小  
  86.     private int mNormalBalloonTextSize; // 正常按键气泡中文本的大小  
  87.     private int mFunctionBalloonTextSize; // 功能按键气泡中文本的大小  

环境设置


十六、EnglishInputProcessor

[html]  view plain  copy
 
  1. /**  
  2.  * Class to handle English input.   
  3.  */  
  4. public class EnglishInputProcessor {  

英文输入发处理器


十七、HandWriteDecoder

[html]  view plain  copy
 
  1. public class HandWriteDecoder {  
  2.     final static String TAG = "HandWriteDecoder";  
  3.     private int mMode = 0;  
  4.       
  5.       
  6.     public void setMode(int mode){  
  7.         mMode = mode;  
  8.     }  
  9.       
  10.     public char[] RecognitionResult(short p[],int len,AssetManager ass){  
  11.         char[] a = null;   
  12.         a = getResult(p,len,mMode,ass,"aiwrite.dat");  
  13.         return a;  
  14.   
  15.     }  
  16.       
  17.     public char[] associate(char p[],int len){  
  18.         char[] a = null;   
  19.         a = getAssociate(p,len);  
  20.         return a;  
  21.     }  
  22.       
  23.       
  24.     static {  
  25.         System.loadLibrary("jni_pateoHandWrite");     
  26.     }  
  27.          
  28.     native char[] getResult(short point[],int len,int mode,AssetManager ass,String path);  
  29.     native char[] getAssociate(char point[],int len);  
  30. }  

手写结果管理类,主要把手写的xy坐标点放入p数组,然后返回相应的识别字结果


十八、HandWriteView

[html]  view plain  copy
 
  1. public class HandWriteView extends View{  
  2.     private final static String TAG = "HandwriteView";  
  3.     private final int WIDTH = 800;  
  4.     private final int CANVAS_HEIGHT = 440;  
  5.     private final int POINT_NUMBER = 500;  
  6.       
  7.     private Bitmap  mBitmap;  
  8.     private Canvas  mCanvas;  
  9.     private Paint   mBitmapPaint;  
  10.     private Rect    mDirtyRect;  
  11.     private Paint   mPaint;  
  12.       
  13.     private short[] mpoint = new short[502];  
  14.     private int length = 0;  
  15.     private boolean isMove = false;  
  16.       
  17.     private long timer = 500;  
  18.       
  19.     private int move_count = 0;  
  20.       
  21.     private PateoIME mService;  
  22.     private Handler mhandler = new Handler();  
  23.     private Runnable Recognition = new Runnable(){  
  24.         public void run() {  
  25.             // TODO Auto-generated method stub  
  26.             if(length == 0){  
  27.                 mService.setPoints(mpoint,length);            
  28.             }else{  
  29.                 mpoint[length]=-1;  
  30.                 mpoint[length+1]=-1;  
  31.                 length=length+2;  
  32.                 mService.setPoints(mpoint,length);            
  33.                 length = 0;  
  34.                 isMove = false;  
  35.             }  
  36.             clear();  
  37.         }  
  38.     };  
  39.       
  40.     public HandWriteView(Context c) {  
  41.         super(c);  
  42.         mService = (PateoIME)c;  
  43.         mBitmap = Bitmap.createBitmap(WIDTH, CANVAS_HEIGHT, Bitmap.Config.ARGB_8888);  
  44.         mCanvas = new Canvas(mBitmap);  
  45.         mBitmapPaint = new Paint(Paint.DITHER_FLAG);  
  46.         mDirtyRect = new Rect(0,0,WIDTH,POINT_NUMBER);  
  47.           
  48.         mPaint = new Paint();  
  49.         mPaint.setAntiAlias(true);  
  50.         mPaint.setDither(true);  
  51.         mPaint.setColor(0xFFFF0000);  
  52.         mPaint.setStyle(Paint.Style.STROKE);  
  53.         mPaint.setStrokeJoin(Paint.Join.ROUND);  
  54.         mPaint.setStrokeCap(Paint.Cap.ROUND);  
  55.         mPaint.setStrokeWidth(6);  
  56.         isMove = false;  
  57.     }  
  58.       
  59.     public void setPaintColor(int color){  
  60.         if(color == 0){  
  61.             color = 0xFFFF0000;  
  62.         }  
  63.         mPaint.setColor(color);  
  64.     }  
  65.       
  66.     public void setStrokeWidth(int size){  
  67.         if(size == 0){  
  68.             mPaint.setStrokeWidth(8);  
  69.         }else if(size == 2){  
  70.             mPaint.setStrokeWidth(4);  
  71.         }else if(size == 3){  
  72.             mPaint.setStrokeWidth(2);  
  73.         }else{  
  74.             mPaint.setStrokeWidth(6);  
  75.         }  
  76.     }  
  77.       
  78.     public void setTimer(long time){  
  79.         if(time == 0){  
  80.             time = 500;  
  81.         }  
  82.         timer = time;  
  83.     }  
  84.       
  85.     @Override  
  86.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
  87.   
  88.         super.onSizeChanged(w, h, oldw, oldh);  
  89.     }  
  90.       
  91.     @Override  
  92.     protected void onDraw(Canvas canvas) {  
  93.         canvas.drawColor(0x00FFFFFF);  
  94.         canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);  
  95.     }  
  96.       
  97.     private float mX, mY;  
  98.       
  99.     private void touch_start(float x, float y) {  
  100.         mX = x;  
  101.         mY = y;  
  102.           
  103.     }  
  104.       
  105.     private void touch_move(float x, float y) {  
  106.   
  107.         mCanvas.drawLine(mX, mY, x, y, mPaint);  
  108.         mX = x;  
  109.         mY = y;  
  110.   
  111.         if(move_count%2 == 0)  
  112.         {  
  113.             invalidate(mDirtyRect);  
  114.         }  
  115.     }  
  116.   
  117.     public void clear(){  
  118.         mBitmap = Bitmap.createBitmap(WIDTH, CANVAS_HEIGHT, Bitmap.Config.ARGB_8888);  
  119.         mCanvas = new Canvas(mBitmap);  
  120.         invalidate();  
  121.     }  
  122.   
  123.       
  124.     @Override  
  125.     public boolean onTouchEvent(MotionEvent event) {  
  126.         return false;  
  127.     }  
  128.       
  129.     public void TouchEvent(MotionEvent event) {  
  130.       float x = event.getX(0);  
  131.       float y = event.getY(0);  
  132.       switch (event.getAction()) {  
  133.           case MotionEvent.ACTION_DOWN:  
  134.               move_count = move_count + 1;  
  135.               mhandler.removeCallbacks(Recognition);  
  136.               addPoints((short)x,(short)y);  
  137.               touch_start(x, y);  
  138.               break;  
  139.           case MotionEvent.ACTION_MOVE:  
  140.               move_count = move_count + 1;  
  141.               isMove = true;  
  142.               mhandler.removeCallbacks(Recognition);  
  143.               addPoints((short)x,(short)y);  
  144.               touch_move(x, y);  
  145.               break;  
  146.           case MotionEvent.ACTION_UP:  
  147.               move_count = 0;  
  148.               invalidate(mDirtyRect);  
  149.             if(isMove == true){  
  150.                 addPoints((short)x,(short)y);  
  151.             }else{  
  152.                 length = 0;  
  153.             }  
  154.             mhandler.postDelayed(Recognition, timer);  
  155.             break;  
  156.       }  
  157.   }  
  158.       
  159.     public void TouchEvent(MotionEvent event,float x,float y) {  
  160.         switch (event.getAction()) {  
  161.             case MotionEvent.ACTION_DOWN:  
  162.                  move_count = move_count + 1;  
  163.                   mhandler.removeCallbacks(Recognition);  
  164.                   addPoints((short)x,(short)y);  
  165.                 touch_start(x, y);  
  166.                 break;  
  167.             case MotionEvent.ACTION_MOVE:  
  168.                  move_count = move_count + 1;  
  169.               isMove = true;  
  170.                   mhandler.removeCallbacks(Recognition);  
  171.                   addPoints((short)x,(short)y);  
  172.                 touch_move(x, y);  
  173.                 break;  
  174.             case MotionEvent.ACTION_UP:  
  175.                  move_count = 0;  
  176.                 invalidate(mDirtyRect);  
  177.                 if(isMove == true){  
  178.                     addPoints((short)x,(short)y);  
  179.                 }else{  
  180.                     length = 0;  
  181.                 }  
  182.               mhandler.postDelayed(Recognition, timer);  
  183.               break;  
  184.         }  
  185.     }  
  186.       
  187.     private void addPoints(short x, short y){  
  188.         if(x<0 || y<0){  
  189.             return;  
  190.         }  
  191.         if(length < POINT_NUMBER - 2){  
  192.             mpoint[length]=x;  
  193.             mpoint[length+1]=y;  
  194.             length=length+2;  
  195.         }  
  196.     }  
  197. }  

手写view,主要通过TouchEvent来获取xy坐标值,来画笔画到画布,其次把xy坐标值输入到Service.setPoints进行最终调用HandWriteDecoder的char[] RecognitionResult(short p[],int len返回识别结果


十九、Log

[html]  view plain  copy
 
  1. public class Log {  
  2.       
  3.     public static boolean mDebug = true;  
  4.       
  5.     public static void d(String tag,String str)  
  6.     {  
  7.         if(mDebug)  
  8.         {  
  9.             android.util.Log.d("PateoInputMethod", "[ " + tag + " ] : " + str);  
  10.         }  
  11.     }  
  12.       
  13.     public static void i(String tag,String str)  
  14.     {  
  15.         if(mDebug)  
  16.         {  
  17.             android.util.Log.i("PateoInputMethod", "[ " + tag + " ] : " + str);  
  18.         }  
  19.     }  
  20.       
  21.     public static void e(String tag,String str)  
  22.     {  
  23.         if(mDebug)  
  24.         {  
  25.             android.util.Log.e("PateoInputMethod", "[ " + tag + " ] : " + str);  
  26.         }  
  27.     }  
  28.       
  29.     public static void w(String tag,String str,Exception e)  
  30.     {  
  31.         if(mDebug)  
  32.         {  
  33.             android.util.Log.w("PateoInputMethod", "[ " + tag + " ] : " + str,e);  
  34.         }  
  35.     }  
  36.   
  37. }  

二十、CandidateViewListener


[html]  view plain  copy
 
  1. /**  
  2.  * Interface to notify the input method when the user clicks a candidate or  
  3.  * makes a direction-gesture on candidate view.  
  4.  */  
  5. /**  
  6.  * 候选词视图监听器接口  
  7.  *   
  8.  * @ClassName CandidateViewListener  
  9.  * @author keanbin  
  10.  */  
  11. public interface CandidateViewListener {  
  12.   
  13.     /**  
  14.      * 选择了候选词的处理函数  
  15.      *   
  16.      * @param choiceId  
  17.      */  
  18.     public void onClickChoice(int choiceId);  
  19.   
  20.     /**  
  21.      * 向左滑动的手势处理函数  
  22.      */  
  23.     public void onToLeftGesture();  
  24.   
  25.     /**  
  26.      * 向右滑动的手势处理函数  
  27.      */  
  28.     public void onToRightGesture();  
  29.   
  30.     /**  
  31.      * 向上滑动的手势处理函数  
  32.      */  
  33.     public void onToTopGesture();  
  34.   
  35.     /**  
  36.      * 向下滑动的手势处理函数  
  37.      */  
  38.     public void onToBottomGesture();  
  39. }  


二十一、CandidateView

[html]  view plain  copy
 
  1. /**  
  2.  * View to show candidate list. There two candidate view instances which are  
  3.  * used to show animation when user navigates between pages.  
  4.  */  
  5. public class CandidateView extends View {  

主要为候选词界面


二十二、CandidatesContainer


[html]  view plain  copy
 
  1. public class CandidatesContainer extends RelativeLayout implements  
  2.         OnTouchListener, AnimationListener, ArrowUpdater {  

候选词集装箱,候选词的管理,管理翻页动画、及其箭头灰画等。


二十三、InputModeSwitcher

[html]  view plain  copy
 
  1. /**  
  2.  * Switcher used to switching input mode between Chinese, English, symbol,etc.  
  3.  */  
  4. public class InputModeSwitcher {  

切换输入法界面,同时提供当前是什么输入法的判断接口,其中该类中涉及到一个有关type的处理方法如下:

[html]  view plain  copy
 
  1. public int requestInputWithSkb(EditorInfo editorInfo) {  

比如定制的收音机输入法界面,应用可以通过type来设置,就可以直接指定显示收音机收入法


二十四、PateoIME

[html]  view plain  copy
 
  1. public class PateoIME extends InputMethodService {  

输入法服务,涉及到如下一些信息:

[html]  view plain  copy
 
  1. // 绑定词库解码远程服务PinyinDecoderService  
  2.         startPinyinDecoderService();  
[html]  view plain  copy
 
  1. /**  
  2.      * 按键处理函数  
  3.      *   
  4.      */  
  5.     private boolean processKey(KeyEvent event, boolean realAction) {  

[html]  view plain  copy
 
  1. // keyCode can be from both hard key or soft key.  
  2. /**  
  3.  * 功能键处理函数  
  4. */  
  5. private boolean processFunctionKeys(int keyCode, boolean realAction) {  

等等view控制等等,比如控制候选view,下面为手写的初始化,大致的看下:

[html]  view plain  copy
 
  1.     mHandWriteView = new HandWriteView(this);  
  2.     mHandWriteWinow = new PopupWindow(mHandWriteView, 800,440);  
  3.     mHandWriteWinow.setBackgroundDrawable(new ColorDrawable(0));  
  4.     mHandWriteWinow.setTouchable(true);  
  5.     mHandWriteWinow.setOutsideTouchable(false);  
  6.     mHandWriteWinow.setClippingEnabled(false);  
  7.     mHandWriteWinow.setTouchInterceptor(new OnTouchListener() {  
  8. ublic boolean onTouch(View v, MotionEvent event) {  
  9.             boolean result = false;  
  10. int num = event.getPointerCount();    
  11.    for(int i=0;i<num;i++){    
  12.     if(i == 0)  
  13.     {  
  14.         switch (event.getAction()) {  
  15.         case MotionEvent.ACTION_DOWN:  
  16.              mHandWriteView.TouchEvent(event);  
  17.              break;  
  18.         case MotionEvent.ACTION_MOVE:  
  19.              mHandWriteView.TouchEvent(event);  
  20.              break;  
  21.         case MotionEvent.ACTION_UP:  
  22.              mHandWriteView.TouchEvent(event);  
  23.              break;  
  24.         }  
  25.     }  
  26.    }  
  27. return result;  
  28.   
  29.     });  
  30.       
  31.     setCandidatesViewShown(true);  


符号界面xml,如下:

[html]  view plain  copy
 
  1. xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <keyboard  
  4.   skb_template="@xml/skb_template1"  
  5.   skb_cache_flag="true"  
  6.   width="10%p"  
  7.   height="23.5%p"  
  8.   key_type="0"  
  9.   repeat="false"  
  10.   balloon="true">  
  11.   
  12.   <row start_pos_x="1.25%p" start_pos_y="2%p" width="9.75%p">  
  13.     <keys splitter="|" labels="<|>|#|_|£|$|€|¥|§|¤"/>  
  14.   row>  
  15.   
  16.   <row start_pos_x="1.25%p" width="9.75%p">  
  17.     <keys splitter=" " labels="¿ ¡ | [ ] { } ^ ~ `"/>  
  18.   row>  
  19.   
  20.   <row start_pos_x="1.25%p" width="9.75%p">  
  21.     <key code="-5"  width="9.75%p"   label="2/2" key_type="7"/>  
  22.     <keys splitter="|" labels="±|×|÷|·|%|°|©"/>  
  23.     <key id="3"/>  
  24.   row>  
  25.   
  26.   <row start_pos_x="1.25%p" key_type="1">  
  27.     <key id="10"/>  
  28.     <key code="-2"  width="9.75%p" repeat="true" key_type="7" icon="@drawable/icon_chinese"  
  29.       icon_popup="@drawable/icon_chinese">  
  30.       <toggle_state state_id="@string/toggle_en_sym" code="-2" icon="@drawable/icon_english"  
  31.       icon_popup="@drawable/icon_english"/>  
  32.       <toggle_state state_id="@string/toggle_hw_sym" code="-2" icon="@drawable/icon_hw"  
  33.       icon_popup="@drawable/icon_hw"/>        
  34.     key>  
  35.     <key label="," width="9.75%p" icon="@drawable/comma_full_icon"  
  36.       icon_popup="@drawable/comma_full_icon" key_type="0">  
  37.     key>  
  38.     <key code="62" key_type="5" width="29.25%p"/>  
  39.     <key label="."  width="9.75%p" key_type="0" icon="@drawable/period_icon"  
  40.       icon_popup="@drawable/period_icon">  
  41.     key>  
  42.     <key id="8"/>  
  43.     <key id="1"/>  
  44.   row>  
  45. keyboard>  

[html]  view plain  copy
 
  1. xml version="1.0" encoding="UTF-8"?>  
  2.   
  3.   <key_type  
  4.     id="0"  
  5.     bg="@drawable/normal_key_bg1"  
  6.     hlbg="@drawable/normal_key_hl_bg"  
  7.     color_highlight="@color/label_color_hl0"/>  
  8.   
  9.     
  10.   <key_type  
  11.     id="1"  
  12.     bg="@drawable/normal_key_bg"  
  13.     hlbg="@drawable/normal_key_hl_bg"/>  
  14.   
  15.     
  16.   <key_type  
  17.     id="2"  
  18.     bg="@drawable/light_key_bg"  
  19.     hlbg="@drawable/light_key_hl_bg"/>  
  20.   
  21.     
  22.   <key_type  
  23.     id="3"  
  24.     bg="@drawable/light_key_up_bg"  
  25.     hlbg="@drawable/light_key_up_hl_bg"/>  
  26.   
  27.     
  28.   <key_type  
  29.     id="4"/>  
  30.   
  31.     
  32.   <key_type  
  33.     id="5"  
  34.     bg="@drawable/normal_key_bg1"  
  35.     hlbg="@drawable/normal_key_hl_bg"  
  36.     color_highlight="@color/label_color_hl0"/>  
  37.   
  38.   <key_type  
  39.     id="6"  
  40.     bg="@drawable/handinput_bg"  
  41.     hlbg="@drawable/handinput_hl_bg"  
  42.     color_highlight="@color/label_color_hl0"/>  
  43.   
  44.     
  45.   <key_type  
  46.     id="7"  
  47.     bg="@drawable/normal_key_bg"  
  48.     hlbg="@drawable/normal_key_hl_bg"/>  
  49.   
  50.     
  51.   <key_type  
  52.     id="8"  
  53.     bg="@drawable/normal_key_bg1"  
  54.     hlbg="@drawable/normal_key_hl_bg"/>  
  55.   
  56.     
  57.   <key_type  
  58.     id="9"  
  59.     color="@color/label_color"  
  60.     bg="@drawable/normal_key_bg1"  
  61.     hlbg="@drawable/normal_key_hl_bg"  
  62.     color_highlight="@color/label_color_hl0"/>  
  63.   
  64.   <key_type  
  65.     id="10"  
  66.     bg="@drawable/normal_key_bg1"  
  67.     hlbg="@drawable/normal_key_bg1"/>  
  68.   
  69.     
  70.   <key_icon code="66" icon="@drawable/enter_icon"  
  71.     icon_popup="@drawable/enter_popup_icon"/>  
  72.   
  73.     
  74.   <key_icon code="62" icon="@drawable/space_icon"  
  75.     icon_popup="@drawable/space_icon"/>  
  76.   
  77.     
  78.   <key_icon code="67" icon="@drawable/delete_icon"  
  79.     icon_popup="@drawable/delete_icon"/>  
  80.   
  81.     
  82.     
  83.   <key id="1" start_pos_x="79.125%p" start_pos_y="72.5%p"  
  84.     width="19.60%p" height="23.5%p" code="66" key_type="7" balloon="false">  
  85.     <toggle_state state_id="@string/toggle_enter_go" label="@string/go" code="66"/>  
  86.     <toggle_state state_id="@string/toggle_enter_search" label="@string/search" code="66"/>  
  87.     <toggle_state state_id="@string/toggle_enter_send" label="@string/sent" code="66"/>  
  88.     <toggle_state state_id="@string/toggle_enter_next" label="@string/next" code="66"/>  
  89.     <toggle_state state_id="@string/toggle_enter_done" label="@string/completion" code="66"/>  
  90.   key>  
  91.   
  92.     
  93.   <key id="2" start_pos_x="73.125%p" start_pos_y="75%p"  
  94.     width="19.60%p" height="22%p" code="66" key_type="0" balloon="false">  
  95.     <toggle_state state_id="@string/toggle_enter_go" label="@string/go" code="66"/>  
  96.     <toggle_state state_id="@string/toggle_enter_search" label="@string/search" code="66"/>  
  97.     <toggle_state state_id="@string/toggle_enter_send" label="@string/sent" code="66"/>  
  98.     <toggle_state state_id="@string/toggle_enter_next" label="@string/next" code="66"/>  
  99.     <toggle_state state_id="@string/toggle_enter_done" label="@string/completion" code="66"/>  
  100.   key>  
  101.   
  102.     
  103.   <key id="3" start_pos_x="79.125%p" start_pos_y="49%p" balloon="false"  
  104.       width="19.60%p" height="23.5%p" code="67" key_type="7"   
  105.       repeat="true"/>  
  106.   
  107.   <key id="4" code="-3" start_pos_x="11.00%p" start_pos_y="72.5%p" balloon="false"  
  108.       width="9.8%p" height="23.5%p" key_type="7" label="\?123" icon="@drawable/symbol_icon"/>  
  109.   
  110.     
  111.   <key id="6" start_pos_x="20.75%p" start_pos_y="72.5%p" balloon="false"  
  112.       width="9.75%p" height="23.5%p" code="-2" key_type="7" repeat="true"   
  113.       icon="@drawable/chinese_input_icon" icon_popup="@drawable/chinese_input_icon">  
  114.       <toggle_state state_id="@string/toggle_en_lower" code="-2" icon="@drawable/english_input_icon" icon_popup="@drawable/english_input_icon"/>  
  115.       <toggle_state state_id="@string/toggle_en_upper" code="-2" icon="@drawable/english_input_icon" icon_popup="@drawable/english_input_icon"/>  
  116.       <toggle_state state_id="@string/toggle_en_first" code="-2" icon="@drawable/english_input_icon" icon_popup="@drawable/english_input_icon"/>  
  117.   key>  
  118.   
  119.     
  120.   <key id="7" start_pos_x="50.50%p" start_pos_y="72.5%p"  
  121.       width="9.75%p" height="23.5%p" label="." key_type="0"  
  122.       icon="@drawable/period_icon" icon_popup="@drawable/period_icon"/>  
  123.   
  124.     
  125.   <key id="8" start_pos_x="69.375%p" start_pos_y="72.5%p"      balloon="false"  
  126.       width="9.75%p" height="23.5%p" label="" code="-7" key_type="7"  
  127.        icon="@drawable/clearbg"  />  
  128.   
  129.     
  130.   <key id="9" start_pos_x="60.125%p" start_pos_y="72.5%p"   balloon="false"  
  131.       width="9.75%p" height="23.5%p" label="@string/hand_write" code="-8"  key_type="7"/>  
  132.     
  133.     
  134.   <key id="10" start_pos_x="1.25%p" start_pos_y="72.5%p" balloon="false"  
  135.       width="9.75%p" height="23.5%p" code="-10" label="" key_type="7"  
  136.       repeat="true" icon="@drawable/icon_speech"/>  
  137.     
  138.   <key id="11" start_pos_x="77.475%p" start_pos_y="34.33%p" balloon="false"  
  139.       width="10.5%p" height="32.33%p" code="-10" label="" key_type="7"  
  140.       repeat="true" icon="@drawable/icon_speech"/>  
  141.     
  142.   <key id="12" start_pos_x="87.9%p" start_pos_y="34.33%p" balloon="false"  
  143.       width="10.5%p" height="32.33%p" label="" code="-7" key_type="7"  
  144.        icon="@drawable/clearbg"  />  
  145.   
  146.   <key id="13" start_pos_x="77.475%p" start_pos_y="66.66%p" balloon="false"  
  147.       width="21.0%p" height="32.33%p" label="@string/completion" code="66" key_type="7"/>         
  148.          
  149.   <key id="14" start_pos_x="58.475%p" start_pos_y="50%p" balloon="false"  
  150.       width="18.975%p" height="49%p" label="," icon="@drawable/comma_full_icon" icon_popup="@drawable/comma_full_icon"/>       
  151.     
  152.   <key id="15" start_pos_x="58.975%p" start_pos_y="50%p"  
  153.       width="18.975%p" height="49%p" label="." icon="@drawable/period_icon" icon_popup="@drawable/period_icon"/>  
  154.   
  155.   <key id="16" start_pos_x="77.475%p" start_pos_y="66.66%p" width="21.0%p" height="32.33%p" label="@string/completion" code="66" balloon="false" keytype="7" >  
  156.       <toggle_state state_id="@string/disable_done" code="-100"  
  157.       label="@string/completion" key_type="7" balloon="false"/>  
  158.   key>  
  159.   
  160.   <key id="17" start_pos_x="87.9%p" start_pos_y="34.33%p" balloon="false"  
  161.       width="10.50%p" height="32.33%p" label="" code="-7" key_type="7" icon="@drawable/clearbg1"/>  
  162.     
  163.   <key id="18" start_pos_x="77.475%p" start_pos_y="34.33%p" balloon="false"   
  164.       width="10.50%p" height="32.33%p" label="" code="-11" key_type="7" icon="@drawable/icon_speech"/>  
  165.   
  166.     
  167.     <key id="20" start_pos_x="79.20%p" start_pos_y="2%p" width="19.5%p" height="48%p" code="67" key_type="7" balloon="false" repeat="true"/>      
  168.     <key id="21" start_pos_x="11.00%p"   start_pos_y="52%p" width="9.8%p" height="48%p" code="-3" key_type="7" label="\?123" icon="@drawable/symbol_icon" balloon="false"/>  
  169.     <key id="22" start_pos_x="69.375%p" start_pos_y="52%p" width="9.75%p" height="48%p" code="-7" key_type="7" icon="@drawable/clearbg" balloon="false"/>   
  170.     <key id="23" start_pos_x="79.20%p" start_pos_y="52%p" width="19.5%p" height="48%p"  code="66" key_type="7" balloon="false">  
  171.         <toggle_state state_id="@string/toggle_enter_go" label="@string/go" code="66"/>  
  172.         <toggle_state state_id="@string/toggle_enter_search" label="@string/search" code="66"/>  
  173.         <toggle_state state_id="@string/toggle_enter_send" label="@string/sent" code="66"/>  
  174.         <toggle_state state_id="@string/toggle_enter_next" label="@string/next" code="66"/>  
  175.         <toggle_state state_id="@string/toggle_enter_done" label="@string/completion" code="66"/>  
  176.     key>  
  177.     <key id="24" start_pos_x="1.25%p"   start_pos_y="52%p" width="9.75%p" height="48%p" code="-10" key_type="7" label="" icon="@drawable/icon_speech" balloon="false"/>    
  178.       
  179.     <key id="30" start_pos_x="62.15%p" start_pos_y="34.6%p" balloon="false"  
  180.       width="15.245%p" height="32.33%p" icon="@drawable/numstar" label="*"  key_type="9"/>     
  181.               
  182.     <key id="31" start_pos_x="62.15%p" start_pos_y="66.6%p" balloon="false"  
  183.       width="15.245%p" height="32.33%p" icon="@drawable/numpound" label="\#"  key_type="9"/>     
  184.         
  185. skb_template>  



相应的显示效果,下面是UE设计图,不为实际显示效果

android 输入法类说明_第3张图片

android 输入法类说明_第4张图片

上面为基本的概率说明


你可能感兴趣的:(android 输入法类说明)