先说明需求,是在输入编辑框EditText中实现输入@字符后其后输入的中文和数字都会高亮,其他字符出现时,自动截断高亮部分。
思路:使用TextWatcher实现监听,对于监听到的文本,使用正则表达式,匹配出符合条件的文本,然后使用SpannableString对其实现高亮。
private TextWatcher textWatcher = new TextWatcher() {
int l = 0;//记录字符串被删除字符之前,字符串的长度
int location = 0;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
l = s.length();
location=mEditContent.getSelectionStart();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (l != s.toString().length()) {
String input = s.toString();
SpannableString msp = new SpannableString(input);
Pattern pattern = Pattern.compile("\\@([a-zA-Z0-9\\u4e00-\\u9fa5]+)");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
int start = matcher.start();
int end = matcher.end();
msp.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.attext_blue)), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
mEditContent.setText(msp);
Editable etable = mEditContent.getText();
Selection.setSelection(etable, location);
}
}
}; 就这么简单,有一个问题,在正则匹配出符合条件的字符后,需要使用SpannableString对其进行颜色设置,然后edittext.setText(span),这里如果不做处理,容易出现死循环。所以在public void beforeTextChanged(CharSequence s, int start, int count, int after)方法里先获取字符串改变之前的长度,然后与输入后的字符串长度做比较。这样就会防止死循环。