zoukankan      html  css  js  c++  java
  • 【移动开发】EditText输入字数限制总结(包括中文输入内存溢出的解决方法)

    限定EditText输入个数的解决方案很多,但是一般主要考虑两点,也就是处理两件事:
    (1)不同语言字符(英文、中文等)处理方式
    (2)输入字符达到数目后,是否仍然允许用户输入

    第一点,涉及的东东其实蛮多,不同语言在不同编码中占据字节数等,不同语言在U8等编码的表示范围等,这一整块知识很丰富,

    自己暂时没有理的特别顺,稍后整理再说吧。

    第二点,目前主流app的处理方案也各有不同,qq5.0以前的版本,发表说说貌似是没有字数限制的(我试了一个350字左右的照样发),

    5.0以后限制了,这样如果用户输入字数超过限制便显示负数,但是仍然允许用户输入,就是不能发表了。这样就把处理权全部交给用户了,

    其实更省事了!

    实现吧。

    方法一:
    布局中限制。
    android:maxLength=10  // 即限制最大输入字符个数为10。
    (1)中英文都算一个字符。
    (2)字数到,不能输入

    方法二:
    InputFilter限制,同布局中限制类似。
    editText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(10)});
    (1)中英文都算一个字符。
    (2)字数到,不能输入

    方法三:
    TextWatcher限制。这里如果字数达到限制仍然允许用户输入的情况不多说,好实现。

    crash问题:使用搜狗输入法时,在字数将要或者已经达到限制之后,一次输入大量中文(不按空格,一直打字,知道搜狗的缓存字符达到上限),

    crash,stackoverflow 内存溢出。呵呵,百度输入法不会哈。

    解决:监听器中动态去除、添加就ok了。见下边方案一

    方案一,中文按两个,英文按一个。个数到限制,用户不能输入
    private TextWatcher textWatcher = new TextWatcher() {
        private int editStart;
        private int editEnd;
        private int maxLen = 10; // the max byte
    	@Override
    	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    		Log.d(TextChanged, ---->beforeTextChanged : start =  + start +  count =  + count +  after =  + after);
    	}
    
    	@Override
    	public void onTextChanged(CharSequence s, int start, int before, int count) {
    	}
    
    	@Override
    	public void afterTextChanged(Editable s) {
    		editStart = opinion.getSelectionStart();
    		editEnd = opinion.getSelectionEnd();
    		// 先去掉监听器,否则会出现栈溢出
    		opinion.removeTextChangedListener(textWatcher);
    		if (!TextUtils.isEmpty(opinion.getText())) {
    			String etstring = opinion.getText().toString().trim();
    			while (calculateLength(s.toString()) > maxLen) {
    				s.delete(editStart - 1, editEnd);
    				editStart--;
    				editEnd--;
    				Log.d(TextChanged, editStart =  + editStart +  editEnd =  + editEnd);
    			}
    		}
    
    		opinion.setText(s);
    		opinion.setSelection(editStart);
    
    		// 恢复监听器
    		opinion.addTextChangedListener(textWatcher);
    		// end by zyf --------------------------
    	}
    	private int calculateLength(String etstring) {
    		char[] ch = etstring.toCharArray();
    
    		int varlength = 0;
    		for (int i = 0; i < ch.length; i++) {
    			// changed by zyf 0825 , bug 6918,加入中文标点范围 , TODO 标点范围有待具体化
    			if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F) || (ch[i] >= 0xA13F && ch[i] <= 0xAA40) || ch[i] >= 0x80) { // 中文字符范围0x4e00 0x9fbb
    				varlength = varlength + 2;
    			} else {
    				varlength++;
    			}
    		}
    		Log.d(TextChanged, varlength =  + varlength);
    		// 这里也可以使用getBytes,更准确嘛
            // varlength = etstring.getBytes(CharSet.forName(GBK)).lenght;// 编码根据自己的需求,注意u8中文占3个字节...
    		return varlength;
    	}
    };


    方案二
    // 达到限制字数后,如果在文字中间输入文字或者空格,最后的字符会被删除
    titleTv.addTextChangedListener(new TextWatcher() {
    
    	@Override
    	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
    	}
    
    	@Override
    	public void onTextChanged(CharSequence s, int start, int before, int count) {
    
    	}
    
    	@Override
    	public void afterTextChanged(Editable s) {
    		 // add by zyf 0825 . 多余的从新输入的位置删除,而不是最后
    		   editStart = opinion.getSelectionStart();
    		   editEnd = opinion.getSelectionEnd();
    
    		if (!TextUtils.isEmpty(titleTv.getText())) {
    			int varlength = 0;
    			int size = 0;
    			String etstring = titleTv.getText().toString().trim();
    			char[] ch = etstring.toCharArray();
    			for (int i = 0; i < ch.length; i++) {
    				size++;
    				if (ch[i] >= 0x4e00 && ch[i] <= 0x9fbb) {
    					varlength = varlength + 2;
    				} else
    					varlength++;
    				if (varlength > 80) {
    					break;
    				}
    			}
    			if (varlength > 80) {
    				 s.delete(size - 1, etstring.length());
    				 // add by zyf 0825 . 多余的从新输入的位置删除,而不是最后
    				 // s.delete(editStart - 1, editEnd); // crash stackoverflow,解决方法参考上边方案一
    			}
    		}
    	}
    
    }); 
  • 相关阅读:
    2016-09-13面试记录
    javascript中的深度拷贝的实现过程及深拷贝的几种方法。
    javascript中的for in循环
    常见的兼容问题及其解决方法。
    一次清空所有数据方法
    数组排序
    css对齐 挖坑~
    css reset样式重置
    CSS 表单
    CSS 表格
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6158000.html
Copyright © 2011-2022 走看看