原文地址: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 plaincopy
  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 plaincopy
  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 plaincopy
  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 plaincopy
  1. /**
  2. * Class used to manage related sound resources.
  3. * 按键声音管理类、单例
  4. */
  5. public class SoundManager {

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

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

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

三、SoftKeyToggle

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

六、SkbTemplate

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

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

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

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

八、SkbContainer

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

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

[html] view plaincopy
  1. /**
  2. * 更新软键盘布局
  3. */
  4. private void updateSkbLayout() {
  5. int screenWidth = mEnvironment.getScreenWidth();
  6. int keyHeight = mEnvironment.getKeyHeight();
  7. int skbHeight = mEnvironment.getSkbHeight();
  8. Resources r = mContext.getResources();
  9. if (null == mSkbFlipper) {
  10. mSkbFlipper = (ViewFlipper) findViewById(R.id.alpha_floatable);
  11. }
  12. mMajorView = (SoftKeyboardView) mSkbFlipper.getChildAt(0);
  13. SoftKeyboard majorSkb = null;
  14. SkbPool skbPool = SkbPool.getInstance();
  15. switch (mSkbLayout) {
  16. case R.xml.skb_qwerty:
  17. majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty,
  18. R.xml.skb_qwerty, screenWidth, skbHeight, mContext);
  19. break;
  20. case R.xml.skb_sym1:
  21. majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym1, R.xml.skb_sym1,
  22. screenWidth, skbHeight, mContext);
  23. break;
  24. case R.xml.skb_sym2:
  25. majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym2, R.xml.skb_sym2,
  26. screenWidth, skbHeight, mContext);
  27. break;
  28. case R.xml.skb_smiley:
  29. majorSkb = skbPool.getSoftKeyboard(R.xml.skb_smiley,
  30. R.xml.skb_smiley, screenWidth, skbHeight, mContext);
  31. break;
  32. case R.xml.skb_phone:
  33. majorSkb = skbPool.getSoftKeyboard(R.xml.skb_phone,
  34. R.xml.skb_phone, screenWidth, skbHeight, mContext);
  35. break;
  36. default:
  37. }
  38. if (null == majorSkb || !mMajorView.setSoftKeyboard(majorSkb)) {
  39. return;
  40. }
  41. mMajorView.setBalloonHint(mBalloonOnKey, mBalloonPopup, false);
  42. mMajorView.invalidate();
  43. }
[html] view plaincopy
  1. @Override
  2. public boolean onTouchEvent(MotionEvent event) {
  3. super.onTouchEvent(event);
  4. if (mSkbFlipper.isFlipping()) {
  5. resetKeyPress(0);
  6. return true;
  7. }
  8. int x = (int) event.getX();
  9. int y = (int) event.getY();
  10. // Bias correction
  11. y = y + mYBiasCorrection;
  12. // Ignore short-distance movement event to get better performance.
  13. if (event.getAction() == MotionEvent.ACTION_MOVE) {
  14. if (Math.abs(x - mXLast) <= MOVE_TOLERANCE
  15. && Math.abs(y - mYLast) <= MOVE_TOLERANCE) {
  16. return true;
  17. }
  18. }
  19. mXLast = x;
  20. mYLast = y;
  21. if (!mPopupSkbShow) {
  22. // mGestureDetector的监听器在输入法服务PinyinIME中。
  23. if (mGestureDetector.onTouchEvent(event)) {
  24. resetKeyPress(0);
  25. mDiscardEvent = true;
  26. return true;
  27. }
  28. }
  29. switch (event.getAction()) {
  30. case MotionEvent.ACTION_DOWN:
  31. resetKeyPress(0);
  32. mWaitForTouchUp = true;
  33. mDiscardEvent = false;
  34. mSkv = null;
  35. mSoftKeyDown = null;
  36. mSkv = inKeyboardView(x, y, mSkvPosInContainer);
  37. if (null != mSkv) {
  38. mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
  39. - mSkvPosInContainer[1], mLongPressTimer, false);
  40. }
  41. break;
  42. case MotionEvent.ACTION_MOVE:
  43. if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
  44. break;
  45. }
  46. if (mDiscardEvent) {
  47. resetKeyPress(0);
  48. break;
  49. }
  50. if (mPopupSkbShow && mPopupSkbNoResponse) {
  51. break;
  52. }
  53. SoftKeyboardView skv = inKeyboardView(x, y, mSkvPosInContainer);
  54. if (null != skv) {
  55. if (skv != mSkv) {
  56. mSkv = skv;
  57. mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
  58. - mSkvPosInContainer[1], mLongPressTimer, true);
  59. } else if (null != skv) {
  60. if (null != mSkv) {
  61. mSoftKeyDown = mSkv.onKeyMove(
  62. x - mSkvPosInContainer[0], y
  63. - mSkvPosInContainer[1]);
  64. if (null == mSoftKeyDown) {
  65. mDiscardEvent = true;
  66. }
  67. }
  68. }
  69. }
  70. break;
  71. case MotionEvent.ACTION_UP:
  72. if (mDiscardEvent) {
  73. resetKeyPress(0);
  74. break;
  75. }
  76. mWaitForTouchUp = false;
  77. // The view which got the {@link MotionEvent#ACTION_DOWN} event is
  78. // always used to handle this event.
  79. if (null != mSkv) {
  80. mSkv.onKeyRelease(x - mSkvPosInContainer[0], y
  81. - mSkvPosInContainer[1]);
  82. }
  83. if (!mPopupSkbShow || !mPopupSkbNoResponse) {
  84. responseKeyEvent(mSoftKeyDown);
  85. }
  86. if (mSkv == mPopupSkbView && !mPopupSkbNoResponse) {
  87. dismissPopupSkb();
  88. }
  89. mPopupSkbNoResponse = false;
  90. break;
  91. case MotionEvent.ACTION_CANCEL:
  92. break;
  93. }
  94. if (null == mSkv) {
  95. return false;
  96. }
  97. return true;
  98. }

九、Settings

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

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

[html] view plaincopy
  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 plaincopy
  1. /**
  2. * Setting activity of Pinyin IME.
  3. */
  4. public class SettingsActivity

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

十一、BalloonHint

[html] view plaincopy
  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 plaincopy
  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. mhandler.postDelayed(Recognition, timer);
  13. break;
  14. }
  15. }

上面为手写输入的view,主要拿到move的xy值,然后把其上一个xy值作为起始值,后续的作为停止值,再这样的逻辑下去,即可以划直线连接相应的点在理论逻辑上不会断点

[html] view plaincopy
  1. mCanvas.drawLine(mX, mY, x, y, mPaint);

针对刷新view,则建议invalidate根据实际的cpu占用来优化

十三、HandWriteDecoder

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

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

十四、KeyMapDream

[html] view plaincopy
  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 plaincopy
  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. * The key height for landscape mode. It is relative to the screen height.
  18. * 横屏按键高度,值是相对于屏幕高度。
  19. */
  20. private static final float KEY_HEIGHT_RATIO_LANDSCAPE = 0.147f;
  21. /**
  22. * The height of the candidates area for portrait mode. It is relative to
  23. * screen height. 竖屏候选词区域的高度,值是相对于屏幕高度。
  24. */
  25. private static final float CANDIDATES_AREA_HEIGHT_RATIO_PORTRAIT = 0.084f;
  26. /**
  27. * The height of the candidates area for portrait mode. It is relative to
  28. * screen height. 横屏候选词区域高度,值是相对于屏幕高度。
  29. */
  30. private static final float CANDIDATES_AREA_HEIGHT_RATIO_LANDSCAPE = 0.125f;
  31. /**
  32. * How much should the balloon width be larger than width of the real key.
  33. * It is relative to the smaller one of screen width and height.
  34. * 猜测:点击软键盘按钮时弹出来的气泡大于按键的宽度的差值,值是相对于屏幕高度和宽度较小的那一个。
  35. */
  36. private static final float KEY_BALLOON_WIDTH_PLUS_RATIO = 0.08f;
  37. /**
  38. * How much should the balloon height be larger than that of the real key.
  39. * It is relative to the smaller one of screen width and height.
  40. * 猜测:点击软键盘按钮时弹出来的气泡大于按键的高度的差值,值是相对于屏幕高度和宽度较小的那一个。
  41. */
  42. private static final float KEY_BALLOON_HEIGHT_PLUS_RATIO = 0.07f;
  43. /**
  44. * The text size for normal keys. It is relative to the smaller one of
  45. * screen width and height. 正常按键的文本的大小,值是相对于屏幕高度和宽度较小的那一个。
  46. */
  47. private static final float NORMAL_KEY_TEXT_SIZE_RATIO = 0.075f;
  48. /**
  49. * The text size for function keys. It is relative to the smaller one of
  50. * screen width and height. 功能按键的文本的大小,值是相对于屏幕高度和宽度较小的那一个。
  51. */
  52. private static final float FUNCTION_KEY_TEXT_SIZE_RATIO = 0.055f;
  53. /**
  54. * The text size balloons of normal keys. It is relative to the smaller one
  55. * of screen width and height. 正常按键弹出的气泡的文本的大小,值是相对于屏幕高度和宽度较小的那一个。
  56. */
  57. private static final float NORMAL_BALLOON_TEXT_SIZE_RATIO = 0.14f;
  58. /**
  59. * The text size balloons of function keys. It is relative to the smaller
  60. * one of screen width and height. 功能按键弹出的气泡的文本的大小,值是相对于屏幕高度和宽度较小的那一个。
  61. */
  62. private static final float FUNCTION_BALLOON_TEXT_SIZE_RATIO = 0.085f;
  63. /**
  64. * The configurations are managed in a singleton. 该类的实例,该类采用设计模式的单例模式。
  65. */
  66. private static Environment mInstance;
  67. private int mScreenWidth; // 屏幕的宽度
  68. private int mScreenHeight; // 屏幕的高度
  69. private int mKeyHeight; // 按键的高度
  70. private int mCandidatesAreaHeight; // 候选词区域的高度
  71. private int mKeyBalloonWidthPlus; // 按键气泡宽度比按键宽度大的差值
  72. private int mKeyBalloonHeightPlus; // 按键气泡高度比按键高度大的差值
  73. private int mNormalKeyTextSize; // 正常按键中文本的大小
  74. private int mFunctionKeyTextSize; // 功能按键中文本的大小
  75. private int mNormalBalloonTextSize; // 正常按键气泡中文本的大小
  76. private int mFunctionBalloonTextSize; // 功能按键气泡中文本的大小

环境设置

十六、EnglishInputProcessor

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

英文输入发处理器

十七、HandWriteDecoder

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

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

十八、HandWriteView

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

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

十九、Log

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

二十、CandidateViewListener

[html] view plaincopy
  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. * @param choiceId
  16. */
  17. public void onClickChoice(int choiceId);
  18. /**
  19. * 向左滑动的手势处理函数
  20. */
  21. public void onToLeftGesture();
  22. /**
  23. * 向右滑动的手势处理函数
  24. */
  25. public void onToRightGesture();
  26. /**
  27. * 向上滑动的手势处理函数
  28. */
  29. public void onToTopGesture();
  30. /**
  31. * 向下滑动的手势处理函数
  32. */
  33. public void onToBottomGesture();
  34. }

二十一、CandidateView

[html] view plaincopy
  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 plaincopy
  1. public class CandidatesContainer extends RelativeLayout implements
  2. OnTouchListener, AnimationListener, ArrowUpdater {

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

二十三、InputModeSwitcher

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

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

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

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

二十四、PateoIME

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

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

[html] view plaincopy
  1. // 绑定词库解码远程服务PinyinDecoderService
  2. startPinyinDecoderService();
[html] view plaincopy
  1. /**
  2. * 按键处理函数
  3. *
  4. */
  5. private boolean processKey(KeyEvent event, boolean realAction) {
[html] view plaincopy
  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 plaincopy
  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. setCandidatesViewShown(true);

符号界面xml,如下:

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <keyboard
  3. skb_template="@xml/skb_template1"
  4. skb_cache_flag="true"
  5. width="10%p"
  6. height="23.5%p"
  7. key_type="0"
  8. repeat="false"
  9. balloon="true">
  10. <row start_pos_x="1.25%p" start_pos_y="2%p" width="9.75%p">
  11. <keys splitter="|" labels="<|>|#|_|£|$|€|¥|§|¤"/>
  12. </row>
  13. <row start_pos_x="1.25%p" width="9.75%p">
  14. <keys splitter=" " labels="¿ ¡ | [ ] { } ^ ~ `"/>
  15. </row>
  16. <row start_pos_x="1.25%p" width="9.75%p">
  17. <key code="-5"  width="9.75%p"   label="2/2" key_type="7"/>
  18. <keys splitter="|" labels="±|×|÷|·|%|°|©"/>
  19. <key id="3"/>
  20. </row>
  21. <row start_pos_x="1.25%p" key_type="1">
  22. <key id="10"/>
  23. <key code="-2"  width="9.75%p" repeat="true" key_type="7" icon="@drawable/icon_chinese"
  24. icon_popup="@drawable/icon_chinese">
  25. <toggle_state state_id="@string/toggle_en_sym" code="-2" icon="@drawable/icon_english"
  26. icon_popup="@drawable/icon_english"/>
  27. <toggle_state state_id="@string/toggle_hw_sym" code="-2" icon="@drawable/icon_hw"
  28. icon_popup="@drawable/icon_hw"/>
  29. </key>
  30. <key label="," width="9.75%p" icon="@drawable/comma_full_icon"
  31. icon_popup="@drawable/comma_full_icon" key_type="0">
  32. </key>
  33. <key code="62" key_type="5" width="29.25%p"/>
  34. <key label="."  width="9.75%p" key_type="0" icon="@drawable/period_icon"
  35. icon_popup="@drawable/period_icon">
  36. </key>
  37. <key id="8"/>
  38. <key id="1"/>
  39. </row>
  40. </keyboard>
[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Copyright (C) 2009 The Android Open Source Project
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. -->
  13. <skb_template
  14. skb_bg="@drawable/skb_bg1"
  15. key_xmargin="0.125%p"
  16. key_ymargin="1.2%p"
  17. balloon_bg="@drawable/key_balloon_bg"
  18. popup_bg="@drawable/miniskb_bg"
  19. color="@color/balloon_color"
  20. color_highlight="@color/label_color"
  21. color_balloon="@color/balloon_color">
  22. <!-- Normal key -->
  23. <key_type
  24. id="0"
  25. bg="@drawable/normal_key_bg1"
  26. hlbg="@drawable/normal_key_hl_bg"
  27. color_highlight="@color/label_color_hl0"/>
  28. <!-- Function key -->
  29. <key_type
  30. id="1"
  31. bg="@drawable/normal_key_bg"
  32. hlbg="@drawable/normal_key_hl_bg"/>
  33. <!-- Light key, light is off -->
  34. <key_type
  35. id="2"
  36. bg="@drawable/light_key_bg"
  37. hlbg="@drawable/light_key_hl_bg"/>
  38. <!-- Light key, light is on -->
  39. <key_type
  40. id="3"
  41. bg="@drawable/light_key_up_bg"
  42. hlbg="@drawable/light_key_up_hl_bg"/>
  43. <!-- key without background-->
  44. <key_type
  45. id="4"/>
  46. <!-- Key with normal background but on-key high-light-->
  47. <key_type
  48. id="5"
  49. bg="@drawable/normal_key_bg1"
  50. hlbg="@drawable/normal_key_hl_bg"
  51. color_highlight="@color/label_color_hl0"/>
  52. <key_type
  53. id="6"
  54. bg="@drawable/handinput_bg"
  55. hlbg="@drawable/handinput_hl_bg"
  56. color_highlight="@color/label_color_hl0"/>
  57. <!-- Function key -->
  58. <key_type
  59. id="7"
  60. bg="@drawable/normal_key_bg"
  61. hlbg="@drawable/normal_key_hl_bg"/>
  62. <!-- Function key -->
  63. <key_type
  64. id="8"
  65. bg="@drawable/normal_key_bg1"
  66. hlbg="@drawable/normal_key_hl_bg"/>
  67. <!-- Normal key -->
  68. <key_type
  69. id="9"
  70. color="@color/label_color"
  71. bg="@drawable/normal_key_bg1"
  72. hlbg="@drawable/normal_key_hl_bg"
  73. color_highlight="@color/label_color_hl0"/>
  74. <key_type
  75. id="10"
  76. bg="@drawable/normal_key_bg1"
  77. hlbg="@drawable/normal_key_bg1"/>
  78. <!-- Default icons for enter key -->
  79. <key_icon code="66" icon="@drawable/enter_icon"
  80. icon_popup="@drawable/enter_popup_icon"/>
  81. <!-- Default icons for space key -->
  82. <key_icon code="62" icon="@drawable/space_icon"
  83. icon_popup="@drawable/space_icon"/>
  84. <!-- Default icons for delete key -->
  85. <key_icon code="67" icon="@drawable/delete_icon"
  86. icon_popup="@drawable/delete_icon"/>
  87. <!-- Default key definition -->
  88. <!-- Enter key for QWERTY-like keyboards.-->
  89. <key id="1" start_pos_x="79.125%p" start_pos_y="72.5%p"
  90. width="19.60%p" height="23.5%p" code="66" key_type="7" balloon="false">
  91. <toggle_state state_id="@string/toggle_enter_go" label="@string/go" code="66"/>
  92. <toggle_state state_id="@string/toggle_enter_search" label="@string/search" code="66"/>
  93. <toggle_state state_id="@string/toggle_enter_send" label="@string/sent" code="66"/>
  94. <toggle_state state_id="@string/toggle_enter_next" label="@string/next" code="66"/>
  95. <toggle_state state_id="@string/toggle_enter_done" label="@string/completion" code="66"/>
  96. </key>
  97. <!-- Enter key for phone keyboard.-->
  98. <key id="2" start_pos_x="73.125%p" start_pos_y="75%p"
  99. width="19.60%p" height="22%p" code="66" key_type="0" balloon="false">
  100. <toggle_state state_id="@string/toggle_enter_go" label="@string/go" code="66"/>
  101. <toggle_state state_id="@string/toggle_enter_search" label="@string/search" code="66"/>
  102. <toggle_state state_id="@string/toggle_enter_send" label="@string/sent" code="66"/>
  103. <toggle_state state_id="@string/toggle_enter_next" label="@string/next" code="66"/>
  104. <toggle_state state_id="@string/toggle_enter_done" label="@string/completion" code="66"/>
  105. </key>
  106. <!-- Delete key.-->
  107. <key id="3" start_pos_x="79.125%p" start_pos_y="49%p" balloon="false"
  108. width="19.60%p" height="23.5%p" code="67" key_type="7"
  109. repeat="true"/>
  110. <key id="4" code="-3" start_pos_x="11.00%p" start_pos_y="72.5%p" balloon="false"
  111. width="9.8%p" height="23.5%p" key_type="7" label="\?123" icon="@drawable/symbol_icon"/>
  112. <!-- Language-switching key. -->
  113. <key id="6" start_pos_x="20.75%p" start_pos_y="72.5%p" balloon="false"
  114. width="9.75%p" height="23.5%p" code="-2" key_type="7" repeat="true"
  115. icon="@drawable/chinese_input_icon" icon_popup="@drawable/chinese_input_icon">
  116. <toggle_state state_id="@string/toggle_en_lower" code="-2" icon="@drawable/english_input_icon" icon_popup="@drawable/english_input_icon"/>
  117. <toggle_state state_id="@string/toggle_en_upper" code="-2" icon="@drawable/english_input_icon" icon_popup="@drawable/english_input_icon"/>
  118. <toggle_state state_id="@string/toggle_en_first" code="-2" icon="@drawable/english_input_icon" icon_popup="@drawable/english_input_icon"/>
  119. </key>
  120. <!-- Period key(English mode). -->
  121. <key id="7" start_pos_x="50.50%p" start_pos_y="72.5%p"
  122. width="9.75%p" height="23.5%p" label="." key_type="0"
  123. icon="@drawable/period_icon" icon_popup="@drawable/period_icon"/>
  124. <!-- clear input switch. -->
  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. <!-- hand input switch. -->
  129. <key id="9" start_pos_x="60.125%p" start_pos_y="72.5%p"   balloon="false"
  130. width="9.75%p" height="23.5%p" label="@string/hand_write" code="-8"  key_type="7"/>
  131. <!-- voice input switch. -->
  132. <key id="10" start_pos_x="1.25%p" start_pos_y="72.5%p" balloon="false"
  133. width="9.75%p" height="23.5%p" code="-10" label="" key_type="7"
  134. repeat="true" icon="@drawable/icon_speech"/>
  135. <key id="11" start_pos_x="77.475%p" start_pos_y="34.33%p" balloon="false"
  136. width="10.5%p" height="32.33%p" code="-10" label="" key_type="7"
  137. repeat="true" icon="@drawable/icon_speech"/>
  138. <key id="12" start_pos_x="87.9%p" start_pos_y="34.33%p" balloon="false"
  139. width="10.5%p" height="32.33%p" label="" code="-7" key_type="7"
  140. icon="@drawable/clearbg"  />
  141. <key id="13" start_pos_x="77.475%p" start_pos_y="66.66%p" balloon="false"
  142. width="21.0%p" height="32.33%p" label="@string/completion" code="66" key_type="7"/>
  143. <key id="14" start_pos_x="58.475%p" start_pos_y="50%p" balloon="false"
  144. width="18.975%p" height="49%p" label="," icon="@drawable/comma_full_icon" icon_popup="@drawable/comma_full_icon"/>
  145. <key id="15" start_pos_x="58.975%p" start_pos_y="50%p"
  146. width="18.975%p" height="49%p" label="." icon="@drawable/period_icon" icon_popup="@drawable/period_icon"/>
  147. <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" >
  148. <toggle_state state_id="@string/disable_done" code="-100"
  149. label="@string/completion" key_type="7" balloon="false"/>
  150. </key>
  151. <key id="17" start_pos_x="87.9%p" start_pos_y="34.33%p" balloon="false"
  152. width="10.50%p" height="32.33%p" label="" code="-7" key_type="7" icon="@drawable/clearbg1"/>
  153. <key id="18" start_pos_x="77.475%p" start_pos_y="34.33%p" balloon="false"
  154. width="10.50%p" height="32.33%p" label="" code="-11" key_type="7" icon="@drawable/icon_speech"/>
  155. <!--handwrite input switch-->
  156. <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"/>
  157. <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"/>
  158. <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"/>
  159. <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">
  160. <toggle_state state_id="@string/toggle_enter_go" label="@string/go" code="66"/>
  161. <toggle_state state_id="@string/toggle_enter_search" label="@string/search" code="66"/>
  162. <toggle_state state_id="@string/toggle_enter_send" label="@string/sent" code="66"/>
  163. <toggle_state state_id="@string/toggle_enter_next" label="@string/next" code="66"/>
  164. <toggle_state state_id="@string/toggle_enter_done" label="@string/completion" code="66"/>
  165. </key>
  166. <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"/>
  167. <key id="30" start_pos_x="62.15%p" start_pos_y="34.6%p" balloon="false"
  168. width="15.245%p" height="32.33%p" icon="@drawable/numstar" label="*"  key_type="9"/>
  169. <key id="31" start_pos_x="62.15%p" start_pos_y="66.6%p" balloon="false"
  170. width="15.245%p" height="32.33%p" icon="@drawable/numpound" label="\#"  key_type="9"/>
  171. </skb_template>

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

上面为基本的概率说明

android 输入法类说明相关推荐

  1. android 输入法类说明

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

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

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

  3. 写一个Android输入法01——最简步骤

    本文演示用Android Studio写一个最简单的输入法.界面和交互都很简陋,只为剔肉留骨,彰显写一个Android输入法的要点. 1.打开Android Studio创建项目,该项目和普通APP的 ...

  4. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建 目录(?)[+] 什么是服务 服务有什么 ...

  5. 实现一个Android输入法

    原文来自 Android Developer Guide,本文为原文翻译,如有错误,欢迎指出. 输入法(IME:Input method editor)是一个能够让用户输入文本的工具.Android提 ...

  6. 浅谈Android输入法(IME)架构

    简介: 输入法 (IME) 是一种可让用户输入文本的用户控件.Android 提供了一种可扩展的输入法框架.借助该框架,应用可以为用户提供备选输入法,例如屏幕键盘,甚至语音输入.安装所需的 IME 后 ...

  7. android输入法框架分析,Android与iOS输入法开发框架比较谈

    对于任何一个使用手机的人,有一样工具是不可能缺少的,它既不是微信之类的社交工具,也不是支付宝之类的金融工具(事实上这两个都越界了),而是输入法这样的输入工具.更重要的是,输入法还是一种特权工具,因为它 ...

  8. android输入法架构解析

    android输入法架构解析 简介: 前阵子接手维护了一个密码键盘的项目,之前还没有接触过android输入法这块的知识点,所以在熟悉项目的同时将android系统输入法实现框架整理了一遍,记录在此. ...

  9. android 输入法如何启动流程_Android输入法显示流程

    Android输入法显示方式大概分为两种:用户手动点击输入框和应用程序设置了输入法自动显示 本文基于Android9.x来分析 目录 1 :viewClicked流程 1.1 viewClicked ...

  10. Android输入法架构学习总结

    此文为本人学习输入法之后所做的一个总结报告.与大家分享. 安卓输入法框架(Input Method Framework)IMF 一.输入法框架简介 自Android平台1.5版本以后,Google开放 ...

最新文章

  1. Hadoop生态圈-hive编写自定义函数
  2. react-native 打包apk
  3. 【模板】最大密度子图
  4. 【渝粤题库】陕西师范大学180208 产品管理 作业(专升本)
  5. python37安装失败_Linux 安装Python37
  6. Java中关于内存泄漏分析和解决方案,都在这里了!
  7. 83-MACD 移动平均汇总/分离指标.(2015.7.3)
  8. 读取properties文件方式
  9. c++STL库最详细介绍(保姆级教学)
  10. mysql front的使用注意要点
  11. php 导出 设置多表头,PHP Excel 导出文件,自定义表头
  12. 大话设计模式之爱你一万年:第十四章 行为模式:命令模式:烧烤天天吃:1.命令模式之烧烤店
  13. Ellisys Bluetooth Sniffer 文档 (EEN-BT09) - 访问链接密钥的方法
  14. CSS基础语法和盒模型
  15. 司空见惯 - 天黑请闭眼
  16. 二分法解一元三次方程c语言,电子技术的应用用二分法解一元三次方程的C++程序:保护环境的广告语...
  17. MYSQL压力测试工具
  18. Launch Failed,Binary not found
  19. python list,元组,字典的相关概念及操作
  20. ios piv6遭拒绝

热门文章

  1. 软媒魔方 6.0.5 正式绿色版
  2. 2020最新Javaweb视频教程-Javaweb从入门到精通【JSP】
  3. CodeSmith(1):使用和语法简介
  4. ENVI 工具箱汉翻译汉化
  5. opencv实际案例(一)银行卡号的识别
  6. booth算法原理的简单化理解
  7. 人工智能是在数学计算机科学控制论信息论,ai人工智能需要学什么 人工智能对数学有何要求...
  8. 动易CMS从word复制粘贴公式
  9. android脚本精灵miui,脚本精灵安卓apk下载
  10. 遭遇nat.exe,socks.exe,USP10.dll,BOSC.dll,kb080387.CNT,~ctwxw.txt等1