android 仿QQ,微信群组里的@功能,支持@多人,并能一键删除,能获取上传对应的id(修改版)

    xiaoxiao2021-03-25  145

    首先注明该文章是借签别人的博客,原文博文地址点击打开链接

    android 仿QQ,微信群组里的@功能,支持@多人,并能一键删除,能获取上传对应的id

    这个需求来源:本人做集成环信聊天时,项目需要@功能,但是环信并没有提供@功能。环信@功能地址点击打开链接

    输入@符号之后进入好友列表 点击某个人,返回这个人的信息,并以@xxx的格式显示在 EditText 中 @部分需要变色 删除的时候需要把“@xxx”整体直接删除 基于以上几点要求,我有个想法: 通过InputFilter判断用户输入,当有“@”符号输入时,跳转到好友列表页,返回用户信息之后,把文字转换成bitmap,用SpannableString 做实现后面的功能 

    UXchatActivity

    package ucux.app.activitys; import android.os.Bundle; import android.text.Spanned; import ucux.app.R; public class UXchatActivity extends BaseActivity implements OnClickListener { public static final int RESULT_CODE_SEND_MEMBER = 32; private EditText mEditTextContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mEditTextContent = (EditText) findViewById(R.id.et_sendmessage); mEditTextContent.setFilters(new InputFilter[]{new MyInputFilter()}); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == RESULT_CODE_SEND_MEMBER) {// @群成员 UxChatUtils.sendMember(this, data, cidNameMap, mEditTextContent); } } @Override public void onClick(View view) { switch (view.getId()) { case R.id.btn_send:// 点击发送按钮(发文字和表情) mChatManager.sendText(s, mPMSessionResult.getPMSID(), UxChatUtils.getAtMemberList(mEditTextContent, cidNameMap)); cidNameMap.clear();// 传完之后清空一下@的列表 break; } } // @群组成员 /** * 存储@的cid、name对 */ private Map<String, String> cidNameMap = new HashMap<>(); /** * 识别输入框的是不是@符号 */ private class MyInputFilter implements InputFilter { @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { if (source.toString().equalsIgnoreCase("@") || source.toString().equalsIgnoreCase("@")) { if (currentChatType() == 2)// 群聊,才能@群组成员 goAt(); } return source; } } private void goAt() { Intent intent = new Intent(UXchatActivity.this, GroupNumberListActivity.class); intent.putExtra("PMSID", mPMSessionResult.getPMSID()); intent.putExtra("SEMDMEMBER", true); startActivityForResult(intent, RESULT_CODE_SEND_MEMBER); } private View.OnLongClickListener longClickListener = new View.OnLongClickListener() { @Override public boolean onLongClick(View view) { try { switch (view.getId()) { case R.id.iv_userhead: EMPM empm = (EMPM) view.getTag(R.id.tag_send_member); Forward lForward = MessageTranslateUtil.TranformForward(empm); if ((currentChatType() == 2) && (lForward != null) && (empm.direct()) && (!UxChatUtils.isExistInMemberList(cidNameMap, lForward.getUID()))) {// 群聊 Intent intent = new Intent(); intent.putExtra(GroupNumberListActivity.KEY_UID, lForward.getUID() + " "); intent.putExtra(GroupNumberListActivity.KEY_NAME, "@" + lForward.getName() + " "); UxChatUtils.sendMember(UXchatActivity.this, intent, cidNameMap, mEditTextContent); } else { return false; } break; } } catch (Exception e) { e.printStackTrace(); } return true; } }; }

    UxChatUtils

    /** * 聊天工具类(新增的) * Created by Administrator on 2017/3/2. */ public class UxChatUtils { //上传需要的uid值 public static ArrayList<String> getAtMemberList(EditText mEditText, Map<String, String> cidNameMap) { ArrayList<String> atMembers = new ArrayList<>(); ArrayList<String> list = new ArrayList<>(); String content = String.valueOf(mEditText.getText().toString().trim()); String[] sss = content.split(" "); for (String s : sss) { list.add(s); } for (int i = 0; i < list.size(); i++) { String keys = ""; Iterator it = cidNameMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object obj = entry.getValue(); if (obj != null && list.get(i).contains((String) obj)) { keys = (String) entry.getKey(); } } if (!TextUtils.isEmpty(keys)) atMembers.add(keys); } return atMembers; } /** * 返回的所有的用户名,用于识别输入框中的所有要@的人 * 如果用户删除过,会出现不匹配的情况,需要在for循环中做处理 */ private static String nameStr; /** * 上一次返回的用户名,用于把要@的用户名拼接到输入框中 */ private static String lastNameStr; public static void sendMember(Context context, Intent data, Map<String, String> cidNameMap, EditText mEditText) { String tmpCidStr = data.getStringExtra(GroupNumberListActivity.KEY_UID); String tmpNameStr = data.getStringExtra(GroupNumberListActivity.KEY_NAME); String[] tmpCids = tmpCidStr.split(" "); String[] tmpNames = tmpNameStr.split(" "); if (tmpCids.length > 0) { for (int i = 0; i < tmpCids.length; i++) { if (tmpNames.length > i) { cidNameMap.put(tmpCids[i], tmpNames[i]); } } } // 这里的lists集合,是把输入框里已经有的人名放进集合中,再在一个一个的比较选择返回的人名,如果是一样的就return,并且不再显示到输入框 ArrayList<String> lists = new ArrayList<String>(); String content = String.valueOf(mEditText.getText().toString().trim()); String[] ssss = content.split(" "); Collections.addAll(lists, ssss); for (int i = 0; i < lists.size(); i++) { if (lists.get(i).equals(tmpNameStr.trim())) { int curIndex = mEditText.getSelectionStart(); if (curIndex >= 1) { mEditText.getText().replace(curIndex - 1, curIndex, ""); } return; } } //返回的人名,自增加 if (nameStr == null) { nameStr = tmpNameStr; } else { nameStr = nameStr + tmpNameStr; } lastNameStr = tmpNameStr; // 获取光标当前位置 int curIndex = mEditText.getSelectionStart(); // 把要@的人插入光标所在位置 mEditText.getText().insert(curIndex, lastNameStr); // 通过输入@符号进入好友列表并返回@的人,要删除之前输入的@ if (curIndex >= 1) { mEditText.getText().replace(curIndex - 1, curIndex, ""); } setAtImageSpan(context, mEditText, nameStr); } private static void setAtImageSpan(final Context context, EditText mEditText, String nameStr) { String content = String.valueOf(mEditText.getText()); if (content.endsWith("@") || content.endsWith("@")) { content = content.substring(0, content.length() - 1); } String tmp = content; SpannableString ss = new SpannableString(tmp); if (nameStr != null) { String[] names = nameStr.split(" "); if (names.length > 0) { for (String name : names) { if (name != null && name.trim().length() > 0) { //把获取到的名字转为bitmap对象 final Bitmap bmp = getNameBitmap(context, name); // 这里会出现删除过的用户,需要做判断,过滤掉 if (tmp.contains(name) && (tmp.indexOf(name) + name.length()) <= tmp.length()) { // 把取到的要@的人名,用DynamicDrawableSpan代替 ss.setSpan(new DynamicDrawableSpan(DynamicDrawableSpan.ALIGN_BASELINE) { @Override public Drawable getDrawable() { BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bmp); drawable.setBounds(0, 0, bmp.getWidth(), bmp.getHeight()); return drawable; } }, tmp.indexOf(name), tmp.indexOf(name) + name.length(), SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE); } } } } } mEditText.setTextKeepState(ss); } /** * 把返回的人名,转换成bitmap * * @param name 人名 * @return 图片 */ private static Bitmap getNameBitmap(Context context, String name) { /* 把@相关的字符串转换成bitmap 然后使用DynamicDrawableSpan加入输入框中 */ name = "" + name; Paint paint = new Paint(); paint.setAntiAlias(true); // 设置字体画笔的颜色 // paint.setColor(context.getResources().getColor(R.color.transculent_black)); paint.setTextSize(30); Rect rect = new Rect(); paint.getTextBounds(name, 0, name.length(), rect); // 获取字符串在屏幕上的长度 int width = (int) (paint.measureText(name)); final Bitmap bmp = Bitmap.createBitmap(width + 5, rect.height() + 5, Bitmap.Config.ARGB_8888);// 长宽+5,可调 Canvas canvas = new Canvas(bmp); canvas.drawColor(context.getResources().getColor(R.color.color_primary)); canvas.drawText(name, rect.left, rect.height() - rect.bottom, paint); return bmp; } /** * 群组成员列表中是否已经有相应的uid * * @param cidNameMap cidNameMap * @param uid uid * @return true-->有 */ public static boolean isExistInMemberList(Map<String, String> cidNameMap, long uid) { try { for (Object o : cidNameMap.entrySet()) { Map.Entry entry = (Map.Entry) o; Object key = entry.getKey(); if (Long.parseLong(key.toString()) == uid) return true; } } catch (Exception e) { e.printStackTrace(); } return false; } }

    GroupNumberListActivity

    if (getIntent().getBooleanExtra("SEMDMEMBER", false)){ // 传回群成员相关信息,并且关闭页面 Intent intent = new Intent(); intent.putExtra(KEY_UID, String.valueOf(mPMSMemberList.get(position).getUID()) + " "); intent.putExtra(KEY_NAME, "@" + mPMSMemberList.get(position).getUName() + " "); setResult(RESULT_OK, intent); finish(); } 在adapter中的头像设置长按监听,长按头像就@那个成员

    holder.iv_avatar.setTag(R.id.tag_send_member, message); holder.iv_avatar.setOnLongClickListener(longClickListener);

    转载请注明原文地址: https://ju.6miu.com/read-10185.html

    最新回复(0)