background
If you need to limit the number of words in the EditText, you can simply set the Android :maxLength attribute in the XML. However, the product requires Toast to prompt the user if the input exceeds the maximum number, and to prevent the user from entering further. 支那
Is the initial scenario handled by implementing TextWatcher, which implements the main requirements logic, or does it run into problems
- Fires again when listening and resetting the text after processing
TextWatcher
The callback - The logic for processing input text to replace selected text is complicated
Problem 1 is easier to handle. Process the text in the onTextChanged method by removing its own TextWatcher object before processing it, and then adding it again after processing the text and resetting it to the EditText. Give up on question 2.
Analysis of the
Since there is the maxLength attribute, then look at the source code is how to implement.
LengthFilter = LengthFilter; LengthFilter = LengthFilter; LengthFilter = LengthFilter; LengthFilter = LengthFilter
public static class LengthFilter implements InputFilter { @UnsupportedAppUsage private final int mMax; public LengthFilter(int max) { mMax = max; } /** * @param source input * @param start input content start position, that is, 0 * @param end input content end position, That is, the length of source * @param dest Existing content * @param dstart where the cursor starts in existing content * @param dend Where the cursor ends in existing content * * @return this input */ public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { int keep = mMax - (dest.length() - (dend - dstart)); if (keep <= 0) { return ""; } else if (keep >= end - start) { return null; // keep original } else { keep += start; if (Character.isHighSurrogate(source.charAt(keep - 1))) { --keep; if (keep == start) { return ""; } } return source.subSequence(start, keep); } } /** * @return the maximum length enforced by this input filter */ public int getMax() { return mMax; }}Copy the code
Look at the logic of source processing, as shown below;
int keep = mMax – (dest.length() – (dend – dstart)); Dest.length () – (end – dstart) is the number of characters left in the current text after the characters to be replaced are removed. In the figure below, replace the “to” in the original text with the “third word”, which limits the maximum length to 5, and the final value of keep is 5-(4-(2-1))=2
Finally, the selected “zhi” will be replaced by the reserved characters 0 to 2 from the four characters of the input “third character”. The result is as follows:
summary
public CharSequence filter(CharSequence source, int start, int end, Spanned dest,int dstart, int dend)
- Source: input content
- Start: indicates the start position of the input content, that is, 0
- End: The end of the input, which is the length of the source
- Dest: indicates the existing content
- Dstart: The starting position of the cursor in the existing content
- Dend: The end position of the cursor in existing content
InputFilter can perform some special judgment and filtering operations on text input, but cannot completely control the content of text.
The solution to the project is also very simple, directly copy the LengthFilter code, in the interception beyond the text to do the corresponding logical processing.
To write it down is to tidy up a little bit just to make a record, and ask the big man to correct the wrong place