限制Edittext输入的字节长度


在给设备重命名时,设备对名字的存储空间一般都是多少字节,而并非多少字,并通常都是采用utf-8的编码。
那问题来了,utf-8的编码是1-6个字节的不等长度,如何获取将一个超过30字节的文本转换到30字节以内?

Java中获取utf-8文本的字节长度很简单,如下:

text.getBytes("utf-8").length


但是在把超过30个字节的字符串截取到30个字节的时候会导致乱码。
如字符串长度是31字节,字符串最后一个是汉字,汉字一般占用3个字节,也就是第[29,30,31]个字节才表示一个汉字,如果截取到30,那么最后的汉字只剩下[29,30]两位来表示了,这个时候就出现先了乱码。
现在就是如何解决取整移除一个字符,防止乱码的出现。
第一步,先把字符串转换为char数组,char在Java中占用两位字节,采用unicode编码;
第二步,把每个char的unicode转换为utf-8编码的长度,计算char的总长  


   |  Unicode符号范围       |  UTF-8编码方式  
 n |  (十六进制)            | (二进制)  
---+-----------------------+------------------------------------------------------  
 1 | 0000 0000 - 0000 007F |                                              0xxxxxxx  
 2 | 0000 0080 - 0000 07FF |                                     110xxxxx 10xxxxxx  
 3 | 0000 0800 - 0000 FFFF |                            1110xxxx 10xxxxxx 10xxxxxx  
 4 | 0001 0000 - 0010 FFFF |                   11110xxx 10xxxxxx 10xxxxxx 10xxxxxx  
 5 | 0020 0000 - 03FF FFFF |          111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  
 6 | 0400 0000 - 7FFF FFFF | 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx  

根据如上Unicode符号与UTF-8编码的对应关系,可以编写一下程序来限制字节长度:

 

public static String getWholeText(String text, int byteCount){
    try {
        if (text != null && text.getBytes("utf-8").length > byteCount) {
            char[] tempChars = text.toCharArray();
            int sumByte = 0;
            int charIndex = 0;
            for (int i = 0, len = tempChars.length; i < len; i++) {
                char itemChar = tempChars[i];
                // 根据Unicode值,判断它占用的字节数
                if (itemChar >= 0x0000 && itemChar <= 0x007F) {
                    sumByte += 1;
                } else if (itemChar >= 0x0080 && itemChar <= 0x07FF) {
                    sumByte += 2;
                } else {
                    sumByte += 3;
                }
                if (sumByte > byteCount) {
                    charIndex = i;
                    break;
                }
            }
            return String.valueOf(tempChars, 0, charIndex);
        }
    } catch (UnsupportedEncodingException e) {
    }
    return text;
}

由于一个char只有两位,最多只能表示utf-8格式的3个字节,这里按照这种方式处理。
另外前面有说utf-8字节的长度是1-6位,这里只计算了3位以内表示的字符,依然不够严谨。下期将给出更为完善的计算方式,可以先参考来实现六位的表示。


附上限制Edittext输入的代码:

public class MaxLimitTextWatcher implements TextWatcher {

	private int mMaxBytes;
	private EditText mEditText;
	
	public MaxLimitTextWatcher(EditText editText, int maxBytes) {
		mEditText = editText;
		mMaxBytes = maxBytes;
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count, int after) {
		
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		Editable editable = mEditText.getText();  
        int len = editable.toString().getBytes().length;  
          
        if(len > mMaxBytes)  
        {
            int selEndIndex = Selection.getSelectionEnd(editable);  
            String str = editable.toString();  
            //截取新字符串  
            String newStr = getWholeText(str, mMaxBytes);
            mEditText.setText(newStr);  
            editable = mEditText.getText();  
              
            //新字符串的长度  
            int newLen = editable.length();
            //旧光标位置超过字符串长度  
            if(selEndIndex > newLen)  
            {
                selEndIndex = editable.length();  
            }
            //设置新光标所在的位置  
            Selection.setSelection(editable, selEndIndex);  
        }
	}

	@Override
	public void afterTextChanged(Editable s) {
		
	}
	
	public static String getWholeText(String text, int byteCount){
	    try {
	        if (text != null && text.getBytes("utf-8").length > byteCount) {
	            char[] tempChars = text.toCharArray();
	            int sumByte = 0;
	            int charIndex = 0;
	            for (int i = 0, len = tempChars.length; i < len; i++) {
	                char itemChar = tempChars[i];
	                // 根据Unicode值,判断它占用的字节数
	                if (itemChar >= 0x0000 && itemChar <= 0x007F) {
	                    sumByte += 1;
	                } else if (itemChar >= 0x0080 && itemChar <= 0x07FF) {
	                    sumByte += 2;
	                } else {
	                    sumByte += 3;
	                }
	                if (sumByte > byteCount) {
	                    charIndex = i;
	                    break;
	                }
	            }
	            return String.valueOf(tempChars, 0, charIndex);
	        }
	    } catch (UnsupportedEncodingException e) {
	    }
	    return text;
	}

}




你可能感兴趣的:(Android,Edittext,MaxLength,utf-8)