奇技淫巧之-EditText控制输入中文10个字英文20个字且不允许特殊字符

备注

这个需求是大家经常用到的,比如在控制用户名输入时经常要用到。

此方法是设置文本监听器,省事,好用,且ROM,平台无关。

code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
private static final String SPECIAL_CHARACTERS = "[\"\"''`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!
@#¥%……&*()—-—+|{}【】‘;:”“’。,、?]";
private static final Pattern NAME_PATTERN;
static {
NAME_PATTERN = Pattern.compile(SPECIAL_CHARACTERS);
}
private TextWatcher textWatcher = new TextWatcher() {
private int editStart;
private int editEnd;
private int maxLen = 20;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
editStart = mEditText.getSelectionStart();
editEnd = mEditText.getSelectionEnd();
mEditText.removeTextChangedListener(textWatcher);
if (!TextUtils.isEmpty(mEditText.getText())) {
String etstring = mEditText.getText().toString().trim();
while (calculateLength(s.toString()) > maxLen) {
s.delete(editStart - 1, editEnd);
editStart--;
editEnd--;
}
}
mEditText.setText(s);
mEditText.setSelection(editStart);
Matcher m = NAME_PATTERN.matcher(s);
if( m.find()){
ToastUtils.showToast(mContext, R.string.robot_name_error);
editStart = mEditText.getSelectionStart();
s.delete( mEditText.getSelectionEnd() - 1, mEditText.getSelectionEnd());
mEditText.setText(s);
mEditText.setSelection(editStart - 1);
}
mEditText.addTextChangedListener(textWatcher);
}
private int calculateLength(String etstring) {
char[] ch = etstring.toCharArray();
int varlength = 0;
for (int i = 0; i < ch.length; i++) {
if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F) || (ch[i] >= 0xA13F
&& ch[i] <= 0xAA40) || ch[i] >= 0x80) {
varlength = varlength + 2;
} else {
varlength++;
}
}
return varlength;
}
};

使用时,只需要

mEditText.addTextChangedListener(textWatcher);

或者使用自定义的EditText类,我写的,目前而言,扩展性实用性还不错,还是可以一用的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;
import android.widget.Toast;
/**
* you can use it like:
* mEditText.setToastString(getResources().getString(R.string.robot_name_error))
* .setWordCountLimit(5)
* .setFormatPattern(SPECIAL_CHARACTERS);
*
* if you want a toast , you must call setToastString(ToastString)
* if you want a custom FormatPattern, you should call setFormatPattern(String str)
* if you want add your TextWatcher, call removeDefaultTextWatcher() first
* if you want get string igno space, call getString()
*/
public class EditTextFormated extends EditText {
private String mToastString;
private int mMaxLen = 20;
private static final String DEFAULT_SPECIAL_CHARACTERS =
"[\"\"''`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*"
+ "()---—-—+|{}【】‘;:”“’。,、?]";
private Pattern mPattern;
public EditTextFormated(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initFormat();
}
public EditTextFormated(Context context, AttributeSet attrs) {
super(context, attrs);
initFormat();
}
public EditTextFormated(Context context) {
super(context);
initFormat();
}
private void initFormat() {
mPattern = Pattern.compile(DEFAULT_SPECIAL_CHARACTERS);
addTextChangedListener(mDefaultTextWatcher);
}
private TextWatcher mDefaultTextWatcher = new TextWatcher() {
private int editStart;
private int editEnd;
private String mBeforeString;
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
mBeforeString = s.toString();
}
public void afterTextChanged(Editable s) {
editStart = getSelectionStart();
editEnd = getSelectionEnd();
removeTextChangedListener(this);
if (!TextUtils.isEmpty(getString())) {
while (calculateLength(s.toString()) > mMaxLen) {
s.delete(editStart - 1, editEnd);
editStart--;
editEnd--;
}
}
Matcher matcher = mPattern.matcher(s);
if (matcher.find()) {
if (mToastString != null) {
Toast.makeText(getContext(), mToastString,
Toast.LENGTH_SHORT).show();
}
setText(mBeforeString);
setSelection(mBeforeString.length());
addTextChangedListener(this);
return;
}
setText(s);
setSelection(editStart);
addTextChangedListener(this);
}
private int calculateLength(String etstring) {
char[] ch = etstring.toCharArray();
int varlength = 0;
for (int i = 0; i < ch.length; i++) {
if ((ch[i] >= 0x2E80 && ch[i] <= 0xFE4F)
|| (ch[i] >= 0xA13F && ch[i] <= 0xAA40)
|| ch[i] >= 0x80) {
varlength = varlength + 2;
} else {
varlength++;
}
}
return varlength;
}
};
/**
* for Personalise TextWatcher you should call this method first
*/
public EditTextFormated removeDefaultTextWatcher() {
removeTextChangedListener(mDefaultTextWatcher);
return this;
}
/**
* get text and ignore spaces
* @return String
*/
public String getString() {
return getText().toString().trim();
}
/**
* set the Special characters Toast string
* @param hint
*/
public EditTextFormated setToastString(String hint) {
mToastString = hint;
return this;
}
public EditTextFormated setWordCountLimit(int len) {
mMaxLen = len;
return this;
}
public EditTextFormated setFormatPattern(String str) {
mPattern = Pattern.compile(str);
return this;
}
}

谢谢大家阅读,如有帮助,来个喜欢或者关注吧!


本文作者:Anderson/Jerey_Jobs

简书地址:Anderson大码渣

github地址:Jerey_Jobs