有用过IM软件的,估计都有用过@功能,首先我们先理一下思路,想实现@功能需要什么功能:
- 在输入框中输入@,弹出一个页面给用户选择所需要@的用户
- 在选择所需要@的用户后,自动填充用户的名字到输入框中(扩展:删除用户名字的空白处,整个用户的名字被删除)
- 接收端接收消息后,对其进行判断是否有@自己
其实,这功能的难点在于如何判断是否有人@自己,在之前,我是通过对于消息的截取进行判断是否有人@自己,但是后来发现假如是名字相同的话,就作废了。
我的解决方式是:
当用户选择所需要@的用户的时候,将所@的用户名称与ObjectID(该用户的唯一标识)存储到一个List中,当发送消息前,遍历List,判断消息中是否包含“@用户名(空白字符(char) (8197))”字段,若不存在,则将该用户数据删掉,然后将所剩下的List数据中的ObjectID以逗号作为分隔符,汇总为一串字符串,然后将需要发送的消息与汇总后的字符串发送给接收端,接收端则显示消息,并且以自身的ObjectID去跟汇总后的字符串进行判断,若包含,则显示[有人@你],若无则无需显示。
OK,思路已经提供了,各位大佬可以去尝试一下。
(只贴关键代码,文末有源码地址)
实现
制作页面

对于发送消息的输入框进行监听:
mEditSendMsg.addTextChangedListener(new 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) {
atFunction(s, start, before, count);
}
@Override
public void afterTextChanged(Editable s) {
}
});
对于文本改动处理:
private String strContent;//存储当前消息
/**
* @param s
* @param start
* @param before
* @param count
* @功能
*/
private void atFunction(CharSequence s, int start, int before, int count) {
String text = String.valueOf(s);
//增加符号
if (before == 0) {
String addText = text.substring(start, start + count);
if (addText.equals("@")) {
showListDialog();
}
} else {
//减少符号(删除用户名字的空白处,整个用户的名字被删除)
String delText = strContent.substring(start, start + before);
if (delText.equals((char) (8197) + "") && start != 0) {
int index = text.lastIndexOf('@', start - 1);
if (index != -1) {
text = text.substring(0, index) + text.substring(start, text.length());
mEditSendMsg.setText(text);
mEditSendMsg.setSelection(index);
}
}
}
strContent = text;
}
提供给用户选择的@用户信息:
private String[] usernames = new String[]{"小简", "小言"};
private String[] objectIs = new String[]{"123", "456"};
private List<UserBean> mBeanList = new ArrayList<>();//存储所@的用户信息
class UserBean {
String username;
String objectID;
}
private void showListDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("请选择需要@的用户");
builder.setItems(usernames, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(MainActivity.this, "你选择的是:" + usernames[which] + " objectID为:" + objectIs[which], Toast.LENGTH_SHORT).show();
//存储所@的用户信息
UserBean bean = new UserBean();
bean.username = usernames[which];
bean.objectID = objectIs[which];
mBeanList.add(bean);
//将所@的名字添加在光标的后面
StringBuilder sb = new StringBuilder(mEditSendMsg.getText().toString());
int selectionEnd = mEditSendMsg.getSelectionEnd();
String strAt = usernames[which] + (char) (8197);
sb.insert(selectionEnd, strAt);
mEditSendMsg.setText(sb.toString());
mEditSendMsg.setSelection(selectionEnd + strAt.length());
}
});
builder.create().show();
}
对于将要的消息进行处理
mBtnSendMsg.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String strMsg = mEditSendMsg.getText().toString();
if (TextUtils.isEmpty(strMsg)) {
return;
}
//发送@信息前再次进行@信息的正确性(避免用户对其进行修改)
for (int index = mBeanList.size() - 1; index >= 0; index--) {
UserBean bean = mBeanList.get(index);
if (!strContent.contains("@" + bean.username + (char) (8197))) {
mBeanList.remove(index);
}
}
//发送消息
if (mBeanList.size() == 0) {
sendTextMsg(strMsg, null);
} else {
StringBuilder strAtUId = new StringBuilder();//存储所@的人的全部id
for (UserBean bean : mBeanList) {
strAtUId.append(bean.objectID);
strAtUId.append(',');
}
if (strAtUId.charAt(strAtUId.length() - 1) == ',') {
strAtUId.deleteCharAt(strAtUId.length() - 1);
}
sendTextMsg(strMsg, strAtUId.toString());
mBeanList.clear();
}
}
});
接收消息,并进行处理(本文的接收端是小言,objectID为456)
/**
* 发送信息
*
* @param msg
* @param objectIDs
*/
protected void sendTextMsg(String msg, String objectIDs) {
mTvReceiveMsg.setText(msg);
//接收端为小言,objectID为456
if (objectIDs == null || !objectIDs.contains("456")) {
mTvAt.setText("无人@你");
}else {
mTvAt.setText("有人@你");
}
}
效果图:


