限制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; } }
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: 如何在EditText中控制输入文本的长度
- 下一篇: 在PHP中使用键值对数组构造JSON数据