现在的位置: 首页 > 综合 > 正文

关于软键盘输入内容删除问题的研究

2013年08月28日 ⁄ 综合 ⁄ 共 4288字 ⁄ 字号 评论关闭

 

首先我们来描叙下我们出现的问题:当我们用软键盘在一个对话框里输入字母后,然后我们想切换下输入方法(例如切换到输入数字),我们就会发现我们开始输入的字母内容不见了,当我们再切换回来输入数字时候我们又会发现我们刚才输入的数字不见,同时又出现了刚才被删除的字母。

  首先我们找到软键盘的处理函数并理解分析:

public void onKey(int primaryCode, int[] keyCodes) {
if (isWordSeparator(primaryCode)) {  //后面定义的函数
//当输入被中断符号中断
// Handle separator
if (mComposing.length() > 0) {
commitTyped(getCurrentInputConnection());
}
sendKey(primaryCode);     //提交完了输出之后,还必须要把这个特殊字符写上
updateShiftKeyState(getCurrentInputEditorInfo());   //看看是否到了特殊的位置,需要改变大小写状态
} else if (primaryCode == Keyboard.KEYCODE_DELETE) {
handleBackspace();
} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {   //但是硬键盘上面的这个好像没用,待考证
//大小写转换
handleShift();
} else if (primaryCode == Keyboard.KEYCODE_CANCEL) {  //左下角那个键,关闭
handleClose();
return;
} else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) {  //这个键,是这样的,前面的LatinKeyboardView这个类里面定义了KEYCODE_OPTIONS
//用来描述长按左下角关闭键的代替。经测试,千真万确
// Show a menu or something'
} else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE  //就是显示着“abc”或者"123"的那个键
&& mInputView != null) {
Keyboard current = mInputView.getKeyboard();
if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) {
current = mQwertyKeyboard;
} else {
current = mSymbolsKeyboard;
}
mInputView.setKeyboard(current);   //改变键盘的根本操作,但是对于具体输入的是大写字母这件事情,还要等按下了之后在做定论
if (current == mSymbolsKeyboard) {
current.setShifted(false);     //测试,这里要是设置为true,打开之后只是shift键的绿点变亮,但是并没有变成另一个符号键盘
}
} else {
handleCharacter(primaryCode, keyCodes);     //这就是处理真正的字符处理函数,不是那些其他的控制键
}
}

从上面的分析来看真正处理字符处理的函数是handleCharacter(primaryCode, keyCodes); 好,我们接下来又发现下这个方法:

private void handleCharacter(int primaryCode, int[] keyCodes) {     //primayCode是键的阿斯课码值
if (isInputViewShown()) {
if (mInputView.isShifted()) {
primaryCode = Character.toUpperCase(primaryCode);   //这才真正把这个字符变成了大写的效果,经测试,没有就不行
//把键盘换成大写的了还不够,那只是从View上解决了问题,一定要这样一句才行
}
}
if (isAlphabet(primaryCode) && mPredictionOn) {       //输入的是个字母,而且允许候选栏显示
mComposing.append((char) primaryCode);            //append(添加)就是把当前的输入的一个字符放到mComposing里面来
getCurrentInputConnection().setComposingText(mComposing, 1);    //在输入目标中也显示最新得到的mComposing.
updateShiftKeyState(getCurrentInputEditorInfo());          //每当输入完结,都要检验是否需要变到大写
updateCandidates();        
} else {
getCurrentInputConnection().commitText(String.valueOf((char) primaryCode), 1); //比如说当输入的是“‘”这个符号的时候,就会掉用这个
//结果就是remove掉所有编辑中的字符,第二个参数的正负,决定着
//光标位置的不同

}
}

从上面的分析我们注意到if (isAlphabet(primaryCode) && mPredictionOn) 语句,这条语句在这里是判断是否字母和对话框显示,我们想想我们的出错现象,不就是输入数字和输入字母处理不同吗?我们就想他们是不是单独计算呢?如是我们就加打印他们的计算长度  mComposing.length();经过打印发现他们是真的单独计算处理,到此我们就想到我们是否能把他们和起来做统一处理,所以我就修改如下:

    private void handleCharacter(int primaryCode, int[] keyCodes) {

        if (isInputViewShown()) {

            if (mInputView.isShifted()) {

                primaryCode = Character.toUpperCase(primaryCode);

            }

        }

        if (isAlphabet(primaryCode) && mPredictionOn) {

            mComposing.append((char) primaryCode);

            getCurrentInputConnection().setComposingText(mComposing, 1);

            updateShiftKeyState(getCurrentInputEditorInfo());

            updateCandidates();

        } else {

 

            //mod by yanzheng 2011-12-27

            mComposing.append((char) primaryCode);

            getCurrentInputConnection().setComposingText(mComposing, 1);

            updateShiftKeyState(getCurrentInputEditorInfo());

            updateCandidates();

           /*

            getCurrentInputConnection().commitText(

                    String.valueOf((char) primaryCode), 1);

                    */

        }

    }

  编译测试发现好了,数字和字母不再排斥了,但是又出现一个问题,那就是我们用硬键盘删除不了那字母和数据,软键盘的删除就行,我们知道硬键盘处理在onKeyDown里,我们研究发现里面并没有对删除键的处理,所以我就在里面加入了处理:

          //add by yanzheng 2011-12-27

              case KeyEvent.KEYCODE_DEL:

                 Log.i(TAG, "KEYCODE_DEL");

                 handleBackspace();

                 return true;            case KeyEvent.KEYCODE_DEL:

                 Log.i(TAG, "KEYCODE_DEL");

                 handleBackspace();

                 return true; 

                 //break;

           

            case KeyEvent.KEYCODE_BACK:

                Log.i(TAG, "****##KEYCODE_BACK: m_iIndexCurKey=" + m_iIndexCurKey+" getRepeatCount() =" +event.getRepeatCount());

                if(m_iKeyBoardShow ==true && mInputView != null)

                {

            handleClose();

            m_iIndexCurKey =-1;

            m_iKeyBoardShow =false;

            return true;

加入内容里调用handleBackspace();方法就是软键盘删除处理方法。编译测试发现行了,我就经过多次测试发现,有时候会出现输入的内容删除以后在接着输入会出现刚才删除的内容有来了,而且从打印的LOG来看,当出现这个现象时候那打印的数据一直出现,就好像系统出问题一样,这个问题也折腾了一天,后来听同事说这个可能是我们频繁安装apk影响的,主要重新编译下系统就行,所以我就按照他们的方法测试了几次发现是那么回事。

抱歉!评论已关闭.