关于EditText选择文字后粘贴出现空格的解决思路

在Android系统里,原生的EditText里输入了字符串后,再长按“选择文字”,“剪切”,“粘贴”,这个字符串的前后会加上空格,这个本来是为了用户体验,告诉用户字符串是粘贴的,但是在某些地方,会因为空格而导致错误,比如Calculator。今天就以Calculator为例,介绍下我的解决思路和想法。因为空格是为了提示用户,所以保留空格,只处理计算结果,后面也会告诉大家该怎么解决空格的。

1.当长按文字后出现ContextMenu

2.然后长按出现"剪切",然后"粘贴",

3.输入"减号"后得到结果,现在是修改好的,没有问题了。

因为要处理最终的输出结果,所以就追踪"="的相关代码。

 在App下的Calculator下就是计算器的相关代码。从main.xml布局中这段代码找到"="的ID.

            <com.android.calculator2.ColorButton
                android:id="@+id/equal"
                android:text="@string/equal"
                style="@style/button_style"
                />


然后根据ID来搜索项目,得到4个类里含有这个字符串,在根据这些类里的方法,判断EventListener.java才是我们要找的。

        case R.id.equal:
            mHandler.onEnter();
            break;


然后点击onEnter()方法,跳转到Logic.java的onEnter()方法了,这里就是最终的计算结果,我们在这里过滤掉空格即可。

    void onEnter() {
	//start add
        String text = getText();
        
                    StringBuilder sb=new StringBuilder();
        for(int i=0;i<text.length();i++){
        	if(text.charAt(i)!=' '){
        		sb.append(text.charAt(i));
        	}
        }
        text=sb.toString();
	//end add
        if (text.equals(mResult)) {
            clearWithHistory(false); //clear after an Enter on result
        } else {
            mHistory.enter(text);
            try {
                mResult = evaluate(text);
            } catch (SyntaxException e) {
                mIsError = true;
                mResult = mErrorString;
            }
            if (text.equals(mResult)) {
                //no need to show result, it is exactly what the user entered
                clearWithHistory(true);
            } else {
                setText(mResult);
                //mEqualButton.setText(mEnterString);
            }
        }
    }


现在计算器这里的结果输出就正常了,大家可以试试自己的手机,HTC G10就是错误的,虚拟机也是错误的。

要想让所有的EditText的空格都没有,因为是"粘贴"之后出现的,所以从"粘贴"跟系统的这个ContextMenu入手。到Framework的base/core/res/res/values/strings.xml里搜索"编辑文字",因为这个字符串比较偏,可以减少大量重复结果。

    <string name="editTextMenuTitle" msgid="1672989176958581452">"编辑文字"</string>


然后用SourceInsight这个软件来搜索name,根据结果显示在TextView.java这个类的onCreateContextMenu(ContextMenu menu)方法里引用了这个name。

        if (added) {
            hideControllers();
            menu.setHeaderTitle(com.android.internal.R.string.editTextMenuTitle);
        }


这里就是创建这个ContextMenu的地方了。

onTextContextMenuItem(int id)这个方法是用来判断用户选择了那个事件,比如“剪切”,“粘贴”等。

            case ID_PASTE:
                CharSequence paste = clip.getText();
				android.util.Log.e("kingfly","kingfly selectText ID_PASTE paste :"+paste.toString()+":>>>>>>");
                if (paste != null && paste.length() > 0) {
                    long minMax = prepareSpacesAroundPaste(min, max, paste);
                    android.util.Log.e("kingfly","kingfly selectText ID_PASTE minMax :"+minMax);
                    min = extractRangeStartFromLong(minMax);
                    max = extractRangeEndFromLong(minMax);
                    android.util.Log.e("kingfly","kingfly selectText ID_PASTE min :"+min+" max :"+max);
                    Selection.setSelection((Spannable) mText, max);
                
                    ((Editable) mText).replace(min, max, paste);
                    
                    stopTextSelectionMode();
                }
                return true;


然后看里面的prepareSpacesAroundPaste(int min, int max, CharSequence paste)这个方法,这个就是用来控制空格的。

    /**
     * Prepare text so that there are not zero or two spaces at beginning and end of region defined
     * by [min, max] when replacing this region by paste.
     */
    private long prepareSpacesAroundPaste(int min, int max, CharSequence paste) {
        // Paste adds/removes spaces before or after insertion as needed.
        android.util.Log.e("kingfly","kingfly prepareSpacesAroundPaste :"+paste);
        if (Character.isSpaceChar(paste.charAt(0))) {
            if (min > 0 && Character.isSpaceChar(mTransformed.charAt(min - 1))) {
                // Two spaces at beginning of paste: remove one
                final int originalLength = mText.length();
				//空格
                ((Editable) mText).replace(min - 1, min, "");
                // Due to filters, there is no garantee that exactly one character was
                // removed. Count instead.
                final int delta = mText.length() - originalLength;
                min += delta;
                max += delta;
            }
        } else {
            if (min > 0 && !Character.isSpaceChar(mTransformed.charAt(min - 1))) {
                // No space at beginning of paste: add one
                final int originalLength = mText.length();
				//空格
                ((Editable) mText).replace(min, min, "");
                // Taking possible filters into account as above.
                final int delta = mText.length() - originalLength;
                min += delta;
                max += delta;
            }
        }

        if (Character.isSpaceChar(paste.charAt(paste.length() - 1))) {
            if (max < mText.length() && Character.isSpaceChar(mTransformed.charAt(max))) {
                // Two spaces at end of paste: remove one
				//空格
                ((Editable) mText).replace(max, max + 1, "");
            }
        } else {
            if (max < mText.length() && !Character.isSpaceChar(mTransformed.charAt(max))) {
                // No space at end of paste: add one
				//空格
                ((Editable) mText).replace(max, max, "");
            }
        }
        
        return packRangeInLong(min, max);
    }


这就是我们一般定位问题的方式,根据字符串或者图片来找到相关的代码,进行修改,一些自己新增的功能则需自己调研了。

相关代码可以自行下载google源码进行分析,我们用的是基于高通平台的2.3.5的代码。

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值