Android EditText话题功能

2016-09-28  本文已影响0人  你就饶了我吧

很多App中都有话题这个功能,类似于微博的话题,以#我是话题#这种形式展现。话题的颜色区分于普通文本的颜色。一般的思路是用正则表达式查找字符串中两个#中间的文字,如果查找到就当作话题,使用Spanable的setSpan方法设置颜色高亮。

代码例子:

MyTextWatcher textWatcher;
EditText mEtContent = (EditText) findViewById(R.id.et_content);
textWatcher = new MyTextWatcher();
mEtContent.addTextChangedListener(textWatcher);

private class MyTextWatcher implements TextWatcher() {
  @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){
      mEtContent.removeTextChangedListener(textWatcher);
      TopicUtils.textviewSpan(context, mEtContent, s.toString());
      mEtContent.addTextChangedListener(textWatcher);
  }
}

TopicUtils.textviewSpan();这个方法就是为话题改变颜色和添加点击事件。
官网上讲It is legitimate to make further changes to s
from this callback, but be careful not to get yourself into an infinite loop, because any changes you make will cause this method to be called again recursively.意思是在afterTextChanged里面对s进行进一步的改变是合法的,但是要小心进入死循环,因为对s的改动会使afterTextChanged方法再次被回调。
所以在TopicUtils.textviewSpan()执行之前removeTextChangedListener ,在执行之后重新addTextChangedListener()。
ok,当我以为万事大吉的时候,有bug来了。原因是部分手机在使用系统的中文输入法时,使用拼音全键这种方式时,每次点击英文字母但是没有选择词语推荐(candidates)的时候都会触发afterTextChanged这个方法。解决办法如下:

private boolean canEdit = true;
private class MyTextWatcher implements TextWatcher() {
  @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){
      if (canEdit) {
            canEdit = false;
            mEtContent.removeTextChangedListener(textWatcher);
            TopicUtils.textviewSpan(context, mEtContent, s.toString());
            mEtContent.addTextChangedListener(textWatcher);
      }
  }
}
上一篇下一篇

猜你喜欢

热点阅读