Android的EditText超出字数限制,给用户提示
导语
如果项目着急使用,直接将下面代码复制到项目中,当做自定义的EditText使用就可以了。
建议将后面的解决思路看一遍,增强自己阅读源码的能力。
自定义的MaxLengthEditText
/*** Created by Kevin on 2016/6/12.* EditText如果限制了最大输入,超出的话,给出相应的提示*/
public class MaxLengthEditText extends EditText {public MaxLengthEditText(Context context, AttributeSet attrs) {super(context, attrs);initLength(attrs, context);}public MaxLengthEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initLength(attrs, context);}private void initLength(AttributeSet a, Context context) {//命名空间(别告诉我不熟悉)String namespace = "http://schemas.android.com/apk/res/android";//获取属性中设置的最大长度int maxLength = a.getAttributeIntValue(namespace, "maxLength", -1);//如果设置了最大长度,给出相应的处理if (maxLength > -1) {setFilters(new InputFilter[]{new MyLengthFilter(maxLength,context)});}}/*** 从源码中复制出来的* 来源:InputFilter.LengthFilter*** 这里只是添加了一句话:* Toast.makeText(context, "字数不能超过" + mMax, Toast.LENGTH_SHORT).show();** This filter will constrain edits not to make the length of the text* greater than the specified length.*/class MyLengthFilter implements InputFilter {private final int mMax;private Context context;public MyLengthFilter(int max, Context context) {mMax = max;this.context = context;}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) {//这里,用来给用户提示Toast.makeText(context, "字数不能超过" + mMax, Toast.LENGTH_SHORT).show();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;}}
}
解决思路
我们是怎么限制输入长度的?
一般,我们是在xml中限制EditText的输入长度的,代码如下:
<EditText
android:id="@+id/edit_text"android:layout_width="match_parent"android:layout_height="wrap_content"android:maxLength="5" />
思考:在EditText的源码中,肯定做了某些操作,使得在字符的长度超过5时,我们没有办法再输入任何内容
所以在EditText中查找“maxLength”,看源码中做了什么操作
在EditText查找maxLength相关的部分
在搜索栏中搜索maxLength,你会得到下面的结果
没有结果,那么我们从EditText的父类TextView中取搜索,会搜索到以下部分:
解读代码
第一张图片的代码
//maxlength的默认值为-1
int maxlength = -1;
第二张图片的代码
//如果设置了maxlength的属性,获取设置的值,否则为-1
case com.android.internal.R.styleable.TextView_maxLength:maxlength = a.getInt(attr, -1);break;
第三张图片的代码
if (maxlength >= 0) {//如果设置了maxlength,给TextView设置相应的过滤器:LengthFilter//具体的操作,可能就在LengthFilter中setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) });
} else {//没有设置maxLength,设置一个空的过滤器setFilters(NO_FILTERS);
}
LengthFilter中代码的分析
/*** This filter will constrain edits not to make the length of the text* greater than the specified length.*/public static class LengthFilter implements InputFilter {private final int mMax;//通过构造方法,将maxlength赋值给mMaxpublic LengthFilter(int max) {mMax = max;}public CharSequence filter(CharSequence source, int start, int end, Spanned dest,int dstart, int dend) {//这里的操作可能不太懂,但是这种格式可以简化一下,成为://int keep = mMax - x;//可以猜想:keep表示当前字符超出maxLength的大小int keep = mMax - (dest.length() - (dend - dstart));//这里对keep的值分别作了判断://keep<=0:也就是当前输入的字符数量大于或者等于maxLength//返回"",当字符数量达到maxLength时,我们不能再输入内容,""符合我们的认知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;}}
如何自定义一个EditText
自定义的EditText代码详情已经在上面的注释加了,这里就不在重复了
结语
看到这里,你可能发现,解决思路也不是很复杂,源码好像也就是那样,只是平常不愿意看而已。
Android作为一个开放的平台,我们一定要利用好源码这一部分来提高自己转载请标明出处http://blog.csdn.net/qq_26411333/article/details/51647888