Android仿微信@好友功能 输入@跳转、删除整块

 更新时间:2017年10月30日 14:44:31   作者:ddssingsong  
这篇文章主要介绍了Android仿微信@好友功能 输入@跳转、删除整块,代码简单易懂,非常不错,具有参考借鉴价值,需要的朋友可以参考下

最近在做聊天功能的时候,有一个需求是仿照微信做@好友的功能,本来以为挺简单,但是做到这块的时候,发现和想象的有点不一样,什么整块删除,块可编辑,总之,加个@的功能很简单,但是要做和微信的一样还是费了一些功夫,下面是一个demo仅供参考,防止遗忘

先上个效果图

这里写图片描述

就是这么个功能

1. 分析需求

输入@跳转到联系人界面,选中一个或者多个好友返回到当前界面

按退格键删除整块内容

块内的内容可编辑,编辑完了之后将不附带@功能,只是单纯的文字

2. 开始编码

既然是文本输入首先继承EditText自定义一个控件

public class MsgEditText extends AppCompatEditText {
 public MsgEditText(Context context) {
  super(context);
 }
 public MsgEditText(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 public MsgEditText(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
 }
}

到底从哪里开始入手呢,首先完成变成块的需求,

无意中看到这个项目https://github.com/g707175425/CloudEditText ,他是这么写的

 private void generateOneSpan(Spannable spannableString, UnSpanText unSpanText) {
  //生成一个TextView
  View spanView = getSpanView(getContext(),  unSpanText.showText.toString(), getMeasuredWidth());
  //再将TextView转换为一个图片
  BitmapDrawable bitmpaDrawable = (BitmapDrawable) UIUtils.convertViewToDrawable(spanView);
  bitmpaDrawable.setBounds(0, 0, bitmpaDrawable.getIntrinsicWidth(), bitmpaDrawable.getIntrinsicHeight());
  //最后将这个图片放到Span里,
  MyImageSpan what = new MyImageSpan(bitmpaDrawable, unSpanText.showText.toString(),unSpanText.returnText);
  final int start = unSpanText.start;
  final int end = unSpanText.end;
  spannableString.setSpan(what, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  //设置一个Span
  spannableString.setSpan(touchableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 }

看到这里我们就记得了一个关于SpanableString的用法,它可以设置图片,可以随意的设置文字的背景的前景,等等一系列比较酷炫的效果,而且只需要一个TextView,如果需要深入了解Span,可自行百度和Google,关于Span的进阶用法,于是就有了下面的实现

//这个是需要成块删除的内容
 private class MyTextSpan extends MetricAffectingSpan {
  private String showText;
  private long userId;
  //userId是为了适应需求,如果不需要请自行去掉
  public MyTextSpan(String showText, long userId) {
   this.showText = showText;
   this.userId = userId;
  }
  public String getShowText() {
   return showText;
  }
  public long getUserId() {
   return userId;
  }
  @Override
  public void updateMeasureState(TextPaint p) {
  }
  @Override
  public void updateDrawState(TextPaint tp) {
  }
 }
 //这个是非整块删除的内容,当然你如果想也是可以删除的
 private class UnSpanText {
  int start;
  int end;
  String returnText;
  UnSpanText(int start, int end, String returnText) {
   this.start = start;
   this.end = end;
   this.returnText = returnText;
  }
 }

刚开始我是这么写的  

//外部调用一个增加Span的方法
 public void addSpan(String showText, String returnText, long userId) {
  getText().append(showText);
  SpannableString spannableString = new SpannableString(getText());
  makeSpan(spannableString, new UnSpanText(spannableString.length() - showText.length(), spannableString.length(), showText, returnText), userId);
  setText(spannableString);
  setSelection(spannableString.length());
 }
 //生成一个需要整体删除的Span
 private void makeSpan(Spannable sps, UnSpanText unSpanText, long userId) {
  MyTextSpan what = new MyTextSpan(unSpanText.returnText, userId);
  int start = unSpanText.start;
  int end = unSpanText.end;
  sps.setSpan(what, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
 }

写到现在这个整块添加已经做好了,下面开始做整块删除,刚开始的时候我是模仿上面的CloudEditText写的,但我发现好像会用各种问题,于是想了一种方法

 @Override
 protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
  super.onTextChanged(text, start, lengthBefore, lengthAfter);
  //向前删除一个字符,@后的内容必须大于一个字符,可以在后面加一个空格
  if (lengthBefore == 1 && lengthAfter == 0) {
   MyTextSpan[] spans = getText().getSpans(0, getText().length(), MyTextSpan.class);
   for (MyTextSpan myImageSpan : spans) {
    if (getText().getSpanEnd(myImageSpan) == start && !text.toString().endsWith(myImageSpan.getShowText())) {
     getText().delete(getText().getSpanStart(myImageSpan), getText().getSpanEnd(myImageSpan));
     break;
    }
   }
  }
 }

上面的意思就是,如果你在EditText中执行删除一个字符的时候,判断前面一个是否是一个Span,如果是自定义的Span就把Span一同删除,关于这个,我可是测试可各种操作才定为这样的

最后是获取需要@的人员名单

 //获取用户Id列表,这只是个参考,可根据需求修改
 public String getUserIdString() {
  MyTextSpan[] spans = getText().getSpans(0, getText().length(), MyTextSpan.class);
  StringBuilder builder = new StringBuilder();
  for (MyTextSpan myTextSpan : spans) {
   String realText = getText().toString().substring(getText().getSpanStart(myTextSpan), getText().getSpanEnd(myTextSpan));
   String showText = myTextSpan.getShowText();
   if (realText.equals(showText)) {
    builder.append(myTextSpan.getUserId()).append(",");
   }
  }
  if (!TextUtils.isEmpty(builder.toString())) {
   builder.deleteCharAt(builder.length() - 1);
  }
  return builder.toString();
 }

最后我就大方的放个地址你们自己看吧

https://github.com/ddssingsong/AtFriend

总结

以上所述是小编给大家介绍的Android仿微信@好友功能 输入@跳转、删除整块,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 很详细的android序列化过程Parcelable

    很详细的android序列化过程Parcelable

    这篇文章主要为大家详细介绍了很详细的android序列化过程Parcelable,代码注释很详细,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • 安卓实现自定义圆形取色盘

    安卓实现自定义圆形取色盘

    这篇文章主要介绍了安卓实现自定义圆形取色盘的相关资料,并且给出了相应的代码,推荐给大家,需要的朋友可以参考下
    2022-08-08
  • Android五子棋游戏程序完整实例分析

    Android五子棋游戏程序完整实例分析

    这篇文章主要为大家分享了Android五子棋游戏程序完整实例,内容丰富,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-04-04
  • 解决Android Studio电脑不支持HAXM的问题

    解决Android Studio电脑不支持HAXM的问题

    这篇文章主要介绍了Android Studio电脑不支持HAXM的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-03-03
  • Android中Fragment的生命周期与返回栈的管理

    Android中Fragment的生命周期与返回栈的管理

    这篇文章主要介绍了Android中Fragment的生命周期与返回栈的管理,举例讲解了Fragment中addToBackStack()方法的使用,需要的朋友可以参考下
    2016-02-02
  • android读取短信示例分享

    android读取短信示例分享

    这篇文章主要介绍了android读取短信示例,需要的朋友可以参考下
    2014-02-02
  • android开发基础教程—文件存储功能实现

    android开发基础教程—文件存储功能实现

    文件存储功能在实现数据读写时会频繁使用到,接下来介绍文件存储功能的实现,感兴趣的朋友可以了解下
    2013-01-01
  • ListView异步加载图片实现思路

    ListView异步加载图片实现思路

    用到ListView去加载数据,加载图片和文字是比较常见的,文字还好,图片从网络请求加载速度比较慢,以下是一个我在项目中使用到的异步加载图片的解决方案
    2013-04-04
  • android自定义等级评分圆形进度条

    android自定义等级评分圆形进度条

    这篇文章主要为大家详细介绍了android自定义等级评分圆形进度条,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-07-07
  • Android ADT 离线下载操作步骤

    Android ADT 离线下载操作步骤

    这篇文章主要介绍了Android ADT 离线下载操作步骤的相关资料,需要的朋友可以参考下
    2017-04-04

最新评论