原文地址:http://blog.youkuaiyun.com/jianguo_liao19840726/article/details/25370407
源码里面有3套输入法,位置:Z:\myandroid\packages\inputmethods
openwnn是一家日本公司开发的开源输入法框架,涉及中文、日文、韩文。目前已经加入到了Android源码之中。因此你打开一个模拟器时,会发现其中有一个japanese ime的输入法,其服务名为openwnn,这个就是openwnn的日文输入法
latin 虚拟即盘
其需要设置的字符通过下面方法传入PateoIME.DecodingInfo decInfo,decInfo中包含了输入的字符,同时进行刷新view
其主要绘制在onDraw的drawForPinyin(canvas);方法中,通过canvas.drawText写入
播放声音前需要注册相应的音频策略,下面为播放声音代码:
相应的上面响应按键的方法被调用在SoftKeyboardView类的下面方法中
上面主要定义的为切换键,相应的配置<toggle_state>
上面主要是软键盘的定义,包括布局和高宽
六、SkbTemplate
上面主要为:共享公共资源软键盘模板,对应xml资源包下的skb_template.xml、可以根据不同的设备来加载不同的公共资源,其他自由也类似
即上面看出缓存了布局模板和软键盘两个列表
上面所说:顶层容器【集装箱】来承载软键盘视图
源码里面有3套输入法,位置:Z:\myandroid\packages\inputmethods
openwnn是一家日本公司开发的开源输入法框架,涉及中文、日文、韩文。目前已经加入到了Android源码之中。因此你打开一个模拟器时,会发现其中有一个japanese ime的输入法,其服务名为openwnn,这个就是openwnn的日文输入法
latin 虚拟即盘
google是PinyinIME ,后续我们加入了手写,为第三方库支持,13年10月份合并手写和拼音输入法!
现在合并后的为PateoIME
上面截图原因,还有个XmlKeyboardLoader.Java
一、ComposingView
- /**
- * View used to show composing string (The Pinyin string for the unselected
- * syllables and the Chinese string for the selected syllables.)
- * 拼音字符串View,用于显示输入的拼音
- */
- public class ComposingView extends View {
其需要设置的字符通过下面方法传入PateoIME.DecodingInfo decInfo,decInfo中包含了输入的字符,同时进行刷新view
- /**
- * Set the composing string to show. If the IME status is
- * {@link PateoIME.ImeState#STATE_INPUT}, the composing view's status will
- * be set to {@link ComposingStatus#SHOW_PINYIN}, otherwise the composing
- * view will set its status to {@link ComposingStatus#SHOW_STRING_LOWERCASE}
- * or {@link ComposingStatus#EDIT_PINYIN} automatically.
- * 设置 解码操作对象,然后刷新View
- */
- public void setDecodingInfo(PateoIME.DecodingInfo decInfo,
- PateoIME.ImeState imeStatus) {
其主要绘制在onDraw的drawForPinyin(canvas);方法中,通过canvas.drawText写入
而上面的setDecodingInfo方法主要在InputMethodService的继承的子类中被调用如下:
- private void updateComposingText(boolean visible) {
- if (!visible) {
- mComposingView.setVisibility(View.INVISIBLE);
- } else {
- mComposingView.setDecodingInfo(mDecInfo, mImeState);
- mComposingView.setVisibility(View.VISIBLE);
- }
- mComposingView.invalidate();
- }
二、SoundManager
- /**
- * Class used to manage related sound resources.
- * 按键声音管理类、单例
- */
- public class SoundManager {
播放声音前需要注册相应的音频策略,下面为播放声音代码:
- public void playKeyDown() {
- if (mAudioManager == null) {
- updateRingerMode();
- }
- if (!mSilentMode) {
- int sound = AudioManager.FX_KEYPRESS_STANDARD;
- mAudioManager.playSoundEffect(sound, FX_VOLUME);
- }
- }
相应的上面响应按键的方法被调用在SoftKeyboardView类的下面方法中
- // If movePress is true, means that this function is called because user
- // moves his finger to this button. If movePress is false, means that this
- // function is called when user just presses this key.
- public SoftKey onKeyPress(int x, int y,
- SkbContainer.LongPressTimer longPressTimer, boolean movePress) {
- if (!movePress) {
- tryPlayKeyDown();
- tryVibrate();
- }
我们项目中是另外的处理方式,其中特别要注意,在应用监听案件事件的时候需要返回true,不然可能按下键盘键听到两次按键音
- /**
- * Class for soft keys which defined in the keyboard xml file. A soft key can be
- * a basic key or a toggling key.
- *
- * @see com.android.inputmethod.pateoime.SoftKey
- */
- public class SoftKeyToggle extends SoftKey {
上面主要定义的为切换键,相应的配置<toggle_state>
四、class SoftKey
上面主要为相应的按键
五、SoftKeyboard
- /**
- * Class used to represent a soft keyboard definition, including the height, the
- * background image, the image for high light, the keys, etc.
- */
- public class SoftKeyboard {
此类中有个很关键的函数,就是通过xy坐标值找到相应的临近按键
- public SoftKey mapToKey(int x, int y) {
六、SkbTemplate
- /**
- * Soft keyboard template used by soft keyboards to share common resources. In
- * this way, memory cost is reduced.
- */
- public class SkbTemplate {
上面主要为:共享公共资源软键盘模板,对应xml资源包下的skb_template.xml、可以根据不同的设备来加载不同的公共资源,其他自由也类似
七、SkbPool
- /**
- * Class used to cache previously loaded soft keyboard layouts.
- */
- public class SkbPool {
上面说明:用来缓存以前加载的软键盘布局,是一个软键盘缓存池,该类有如下两个变量
- private Vector<SkbTemplate> mSkbTemplates = new Vector<SkbTemplate>();
- private Vector<SoftKeyboard> mSoftKeyboards = new Vector<SoftKeyboard>();
即上面看出缓存了布局模板和软键盘两个列表
八、SkbContainer
- /**
- * The top container to host soft keyboard view(s).
- */
- public class SkbContainer extends RelativeLayout implements OnTouchListener {
上面所说:顶层容器【集装箱】来承载软键盘视图
- /**
- * 更新软键盘布局
- */
- private void updateSkbLayout() {
- int screenWidth = mEnvironment.getScreenWidth();
- int keyHeight = mEnvironment.getKeyHeight();
- int skbHeight = mEnvironment.getSkbHeight();
- Resources r = mContext.getResources();
- if (null == mSkbFlipper) {
- mSkbFlipper = (ViewFlipper) findViewById(R.id.alpha_floatable);
- }
- mMajorView = (SoftKeyboardView) mSkbFlipper.getChildAt(0);
- SoftKeyboard majorSkb = null;
- SkbPool skbPool = SkbPool.getInstance();
- switch (mSkbLayout) {
- case R.xml.skb_qwerty:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_qwerty,
- R.xml.skb_qwerty, screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_sym1:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym1, R.xml.skb_sym1,
- screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_sym2:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_sym2, R.xml.skb_sym2,
- screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_smiley:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_smiley,
- R.xml.skb_smiley, screenWidth, skbHeight, mContext);
- break;
- case R.xml.skb_phone:
- majorSkb = skbPool.getSoftKeyboard(R.xml.skb_phone,
- R.xml.skb_phone, screenWidth, skbHeight, mContext);
- break;
- default:
- }
- if (null == majorSkb || !mMajorView.setSoftKeyboard(majorSkb)) {
- return;
- }
- mMajorView.setBalloonHint(mBalloonOnKey, mBalloonPopup, false);
- mMajorView.invalidate();
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- super.onTouchEvent(event);
- if (mSkbFlipper.isFlipping()) {
- resetKeyPress(0);
- return true;
- }
- int x = (int) event.getX();
- int y = (int) event.getY();
- // Bias correction
- y = y + mYBiasCorrection;
- // Ignore short-distance movement event to get better performance.
- if (event.getAction() == MotionEvent.ACTION_MOVE) {
- if (Math.abs(x - mXLast) <= MOVE_TOLERANCE
- && Math.abs(y - mYLast) <= MOVE_TOLERANCE) {
- return true;
- }
- }
- mXLast = x;
- mYLast = y;
- if (!mPopupSkbShow) {
- // mGestureDetector的监听器在输入法服务PinyinIME中。
- if (mGestureDetector.onTouchEvent(event)) {
- resetKeyPress(0);
- mDiscardEvent = true;
- return true;
- }
- }
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- resetKeyPress(0);
- mWaitForTouchUp = true;
- mDiscardEvent = false;
- mSkv = null;
- mSoftKeyDown = null;
- mSkv = inKeyboardView(x, y, mSkvPosInContainer);
- if (null != mSkv) {
- mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- - mSkvPosInContainer[1], mLongPressTimer, false);
- }
- break;
- case MotionEvent.ACTION_MOVE:
- if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) {
- break;
- }
- if (mDiscardEvent) {
- resetKeyPress(0);
- break;
- }
- if (mPopupSkbShow && mPopupSkbNoResponse) {
- break;
- }
- SoftKeyboardView skv = inKeyboardView(x, y, mSkvPosInContainer);
- if (null != skv) {
- if (skv != mSkv) {
- mSkv = skv;
- mSoftKeyDown = mSkv.onKeyPress(x - mSkvPosInContainer[0], y
- - mSkvPosInContainer[1], mLongPressTimer, true);
- } else if (null != skv) {
- if (null != mSkv) {
- mSoftKeyDown = mSkv.onKeyMove(
- x - mSkvPosInContainer[0], y
- - mSkvPosInContainer[1]);
- if (null == mSoftKeyDown) {
- mDiscardEvent = true;
- }
- }
- }
- }
- break;
- case MotionEvent.ACTION_UP:
- if (mDiscardEvent) {
- resetKeyPress(0);
- break;
- }
- mWaitForTouchUp = false;