相信大家在使用IM软件中的时候肯定会使用到@功能
这里实现其实需要考虑步骤
1.@弹出群员框的弹出
2.如何间隔@XX的对象
3.如何删除@功能
4.重复选择@人功能的筛选
5.@列表传输
首先,我们需要获取一个群员列表,建群的时候,进入聊天界面之后就需要获取一份群成员列表。
先探讨第一个问题,弹出@列表,在每次EditText触发onTextChanged胡时候调用下面的onAtTextChanged,弹出列表,然后选择后添加到@的列表中,
这里需要考虑同时出现多个@的情况
每个@的成员,需要有一个空格来间隔,微信也是这样处理的,
删除@的人员的时候需要通过检查空格检测到最近的一个是否是成员。
```
/**
* 最近一次at的索引
*/
private var mLastAtIndex = -1
/**
* at输入变更回调
* @param inputText 输入框
* @param start 当前光标在的索引
* @param before
* @param count
*/
private fun onAtTextChanged(inputText: EditText, start: Int, before: Int, count: Int) {
val add = count > before
ALog.d(TAG, "onAtTextChanged add: $add, mLastAtIndex: $mLastAtIndex")
if (mLastAtIndex >= 0) {//表示当前在at中
//表示在@前插入文本,这时候就不处理,不用过滤@列表,只是增删上一次a@的位置索引
if (start <= mLastAtIndex) {
if (add) {
mLastAtIndex += count
} else {
//如果删除位置是当前的@位置,且之前原位置大于当前@位置,表示当前的@被删除了,取消@状态
if (start + before > mLastAtIndex) {
showAtList(false) //弹出@成员列表
} else {
mLastAtIndex -= before //设置上一个@的位置
}
}
} else {
//如果是在@后插入的文本,则作为搜索条件来查询@成员
val search = inputText.text.substring(mLastAtIndex + 1)
ALog.d(TAG, "onAtTextChanged search: $search")
Observable.create(ObservableOnSubscribe<List<Recipient>> {
try {
it.onNext(mAllAtList.filter {
it.address.serialize().contains(search) ||
it.profileName?.contains(search, true) == true ||
it.systemDisplayName?.contains(search, true) == true
})
} finally {
it.onComplete()
}
}).subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.compose(RxLifecycle.bind(this).toLifecycleTransformer())
.subscribe({
mChatAtAdapter.setAtList(it, search) //群成员中有搜索功能
}, {
ALog.e(TAG, "onAtTextChanged error", it)
})
}
//如果变回小于0,则不在显示@列表
if (mLastAtIndex < 0) {
showAtList(false)
}
} else {
if (add) {
//如果新输入的字符是@,则进入at状态,并
val target = inputText.text.substring(start, start + count)
if (target == GroupViewModel.CHAT_AT_CHAR) {
mLastAtIndex = start
showAtList(true)
}
} else {
//如果是回退,则判断当前文本最后是否以@结尾,如果是则一并删除