In Android development, you often encounter the requirement that the text content entered in the input box should limit 10 characters or 20 letters. Before also on the internet to see a lot of solutions, the effect is not very good, most are directly to take the length of the string () as a limited basis for the judgement, this idea is very wrong, simple with string.length (), to determine the length of strings, letters and characters of the same length, So we have to think about it a different way.
According to "10 characters or 20 letters of requirement", we can see that the relationship between the length of the Chinese character and the letter is 1:2, so we have to encode the string, which is to achieve the ratio relationship between the Chinese character and the letter 1:2, where we use GB2312 encoding, different encoding formats, The ratio relation is different, here everybody should notice ...
For example:
String content = Edittext.gettext (). toString ();
byte[] bt = content.getbytes ("gb2312");
Here you get the data in the input box and encode the string into the byte[] array.
The next step is to judge the length, note here, using the "gb2312" code, according to the above "10 characters or 20 letters" requirements, the maximum length is 20
if (bt.length >20)
{
The action to be processed ....
}
Here you should pay attention to a place, is once the string length beyond the interception and conversion, and the position of the cursor problem, especially the latter many people will forget.
The first is interception, will be more than the string interception, of course, here must first be encoded in the interception, but also is byte[] array interception, here I would like to provide you with a method
Private byte[] subbytes (byte[] src, int begin, int count) {
byte[] bs = new Byte[count];
System.arraycopy (SRC, begin, BS, 0, Count);
return BS;
}
When used directly:
String str = editable.tostring ();
byte[] Bt2 = str.getbytes ("gb2312");
byte[] bt3 = subbytes (bt2,0,20);
After the interception, of course, the contents of the byte array will be translated into a string form, I would like to provide you with a method
private string gbtostring (byte[] Data {
string str = null;
try {
str = new String (data, "gb2312");
\ catch (unsupportedencodingexception e) {
} return
STR;
}
When used directly
String newstrs = gbtostring (BT3);
Edittext.settext (Newstrs);
Finally is the question of the cursor, must put to the last side ...
int selendindex = selection.getselectionend (editable);
Sets the position of the new cursor
selection.setselection (editable, selendindex);
Of course, this program is written so that it seems to be able to implement functionality, but if you revisit the logic, you can still find a loophole. Maybe someone will not understand, I will share the bug map directly:
Why this bug is present. In fact, the key is in the final intercept of the string. The relationship between Chinese characters and letters is 1:2, if the user input 9 characters after entering a letter, then the length of 19. At this time if the last in the input of a Chinese character, then the length is 21, intercept the first 20, resulting in the last one of the Chinese character is cut half, and then in the transcoding into character characters will inevitably garbled. How to solve this bug. In fact, there are many ways, I also walked some detours, until the squat pit bored suddenly thought of a very simple treatment method.
1, since it is the interception of the last character after the conversion of the problem, then we judge the last character of the string after the turn is not garbled, if it is that cut off, not on the reservation. Since the input box is reserved only for Chinese characters and English letters, we can directly determine whether the last character is a Chinese character or a letter. Here I offer two methods of judgment, both of which I put into the StringUtils class.
/**
* Determine if the string contains the Chinese
*
str
@return
/Public
Static Boolean Iscontainchinese (String str) {pattern
p = pattern.compile ("[\u4e00-\u9fa5]");
Matcher m = p.matcher (str);
return M.find ();
}
/**
* Determine if the string contains the letter
*
str
@return
/public static Boolean iscontainletters (String str) {for
(char i = ' A '; I <= ' Z '; i++) {
if (str.contains string.valueof (i) )) {return
true;
}
}
for (char i = ' a '; I <= ' z '; i++) {
if (Str.contains (string.valueof (i)) {return
true;
}
}
return false;
}
There is a way to judge, the next thing is to fill the funnel:
String temp = string.valueof (Newstrs.charat (Newstrs.length ()-1));
Boolean flag = Stringutil.iscontainchinese (temp);
Boolean flag2 = stringutil.iscontainletters (temp);
if (!flag &&!flag2) {
String newStrs2 = newstrs.substring (0,newstrs.length ()-1);
Edittext.settext (NEWSTRS2);
} else {
edittext.settext (newstrs);
}
The condition of the two interception here is that the converted string is not a character or a letter before it is executed (if you want to include other characters, you can judge it again).
Now look at the effect:
The last garbled is intercepted. It can be said to be perfect.
There is also a knowledge point to mention, on the text of the EditText text monitoring, I personally think that the best effect with textwatcher, because it can be very convenient to customize the content implementation.
Say so much, give everybody dedicate complete code is the hard truth.
public class Watchertext implements Textwatcher {private int maxlen = 0;
Private EditText edittext = null;
Public watchertext (int maxlen, EditText edittext) {this.maxlen = MaxLen;
This.edittext = EditText; } public void aftertextchanged (Editable arg0) {//TODO auto-generated method stub} public void is Foretextchanged (charsequence arg0, int arg1, int arg2, int arg3) {//TODO auto- Generated method stub} public void OnTextChanged (charsequence arg0, int arg1, int arg2, int arg3) {try
{//TODO auto-generated method stub Editable Editable = Edittext.gettext ();
String content = Edittext.gettext (). toString ();
byte[] bt = content.getbytes ("gb2312");
if (Bt.length >maxlen) {toastutil.showerrorinfotip ("Enter the number of characters exceeding limit"); int selendindex = selection.getselectionend (editable);
String str = editable.tostring ();
byte[] Bt2 = str.getbytes ("gb2312");
byte[] bt3 = subbytes (Bt2,0,maxlen);
String newstrs = gbtostring (BT3);
String temp = string.valueof (Newstrs.charat (Newstrs.length ()-1));
Boolean flag = Stringutil.iscontainchinese (temp);
Boolean flag2 = stringutil.iscontainletters (temp);
if (!flag &&!flag2) {String newStrs2 = newstrs.substring (0,newstrs.length ()-1);
Edittext.settext (NEWSTRS2);
}else {edittext.settext (newstrs);
} editable = Edittext.gettext ();
The length of the new string int newlen = Editable.length (); The old cursor position exceeds the string length if (selendindex >= newlen) {selendindex = editable.
Length (); //Set the position of the new cursorPlacing Selection.setselection (editable, selendindex);
} catch (Unsupportedencodingexception e) {e.printstacktrace ();
} private byte[] subbytes (byte[] src, int begin, int count) {byte[] bs = new Byte[count];
System.arraycopy (SRC, begin, BS, 0, Count);
return BS;
private string gbtostring (byte[] Data {string str = NULL;
try {str = new String (data, "gb2312");
catch (Unsupportedencodingexception e) {} return str; }
}
When used outside the direct
EditText EditText = (edittext) Findviewbyid (r.id.entry);
Edittext.addtextchangedlistener (New Watchertext (Max_num, EditText));
If there is a wrong place, you are welcome to correct the big God, thank you.