@功能实现

3,121 阅读3分钟

有用过IM软件的,估计都有用过@功能,首先我们先理一下思路,想实现@功能需要什么功能:

  1. 在输入框中输入@,弹出一个页面给用户选择所需要@的用户
  2. 在选择所需要@的用户后,自动填充用户的名字到输入框中(扩展:删除用户名字的空白处,整个用户的名字被删除)
  3. 接收端接收消息后,对其进行判断是否有@自己

其实,这功能的难点在于如何判断是否有人@自己,在之前,我是通过对于消息的截取进行判断是否有人@自己,但是后来发现假如是名字相同的话,就作废了。

我的解决方式是:

当用户选择所需要@的用户的时候,将所@的用户名称与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("有人@你");
        }

    }

效果图:

最后,附上源码地址,便于对照查看使用。

源码链接