如标题所说, 今天要实现 @ 的效果, 明确要实现的效果边界:
- 输入 @ 字符, 弹出一界面选择好友(监听回调)
- 选择好友后更新 @ 的内容
- 删除 @ 内容将一次删除 @+好友名 所有字符
废话不多说, 先上效果图:
效果图中我打开好友列表以延时500ms随机取名字代替:
@Override
public void triggerAt() {
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
atTextWatcher.insertTextForAt(et, names[random.nextInt(names.length)]);
}
}, 500);
}
下面说下具体的实现方法:
首先使用 TextWatcher 是毋庸置疑的, 通过分析微信 @ 功能, 发现 @张三 分为三部分:
- 第一部分为@功能的开始符号 @ 字符
- 第二部分为好友名字
- 第三部分为@功能的结束符号 ’ ’
- 注意: 通过分析微信中结束符号, 发现它并不是空格, 而是 unicode 编码为 8197 的字符, 该字符跟空格符长得一样但其实是两个东西
分析完思路就有了:
-
- 通过TextWatcher监听EditText
-
- 监听到内容增加一字符并且该字符为 @ 符号执行监听, 弹出选择好友界面, 并记录 @ 符号位置
-
- 当监听到删除一字符并且该字符为@功能结束符, 编码为 8197 的字符, 根据结束符位置往前找 @ 符号, 并移除之间的内容
实现:
- 我定义了 AtTextWatcher 实现 TextWatcher, 来处理 @ 效果, 在
onTextChanged
中判断新增字符是否为 @ , 如果是执行回调AtListener.triggerAt()
方法(Activity 中实现此方法打开好友列表选择好友), 并记录 @ 字符的位置. - 外部选择好友完成后, 调用方法
AtTextWatcher.insertTextForAt("选择的好友名字")
, 将好友名字和结束符号插入到记录的**@**符号后面 - 监听删除 @字符串 的逻辑必须写在监听方法
beforeTextChanged
中, 因为执行该方法时删除的字符并未从EditText中移除, 可以拿到字符并判断是否是