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仿微信@好友功能 输入@跳转、删除整块,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Android中使用listview实现qq/微信好友列表

    首先附上运行结果: 如果你没有学过listview请你先看一看基本知识.不想再说的那么细了 太多了. 首先是listview布局 <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lv_view" android

  • android 实现类似微信缓存和即时更新好友头像示例

    引言 使用微信时我们会发现,首次进入微信的好友列表时,会加载好友头像,但是再次进入时,就不用重新加载了,而且其他页面都不用重新加载,说明微信的好友头像是缓存在本地的,然后好友修改头像后,又会及时的更新,这个功能是如何实现的呢,我们来分析一下 分析 关于头像缓存的实现 头像是网络图片,而且数据量较大,如果用我们常用的SharedPreferences将头像以Bitmap的形式存储,势必会造成OOM,这个方法是行不通的,我们存储的只能是图片的地址,但是如果只存储地址的话,要转化成图片,还是要通过网络

  • Android实现分享微信好友及出现闪退的解决办法

     1.申请微信APPID 要实现分享到微信的功能,首先要到微信开放平台申请一个APPID.但在申请APPID的时候需要填写一个应用签名和应用包名.需要注意的是包名必须与开发应用时的包名一致,应用签名也必须去掉冒号而且字母为小写. 2.应用签名的获取 开发android应用的人很多,很有可能类名.包名起成了同一个名字,签名这时候就起到区分的作用. 所有的Android应用都必须有数字签名,不存在没有数字签名的应用,包括模拟器运行的.模拟器开发环境,开发时,通过ADB接口上传的程序会自动被签有Deb

  • Android中使用ListView模拟微信好友功能

    效果图: 分析: 1.创建listView 2.创建数据 3.创建适配器 将数据放到呈现数据的容器里面. 将这个容器(带数据)连接适配器. 其实是直接在我们自己写的adapter的getView重载方法中返回连接的view. View view=View.inflate(mContext, com.example.weChatFriends.R.layout.item_friend, null); return view; 4.ListView设置适配器 代码: package fry; imp

  • Android仿微信雷达辐射搜索好友(逻辑清晰实现简单)

    不知不觉这个春节也已经过完了,遗憾家里没网,没能及时给大家送上祝福,今天回到深圳,明天就要上班了,小伙伴们是不是和我一样呢?今天讲的是一个大家都见过的动画,雷达搜索好友嘛,原理也十分的简单,你看完我的分析,也会觉得很简单了,国际惯例,无图无真相,我们先看看效果图,对了,真 测试机送人了,所讲这段时间应该一直用模拟器显示吧! 仿微信雷达扫描,仿安卓微信.云播雷达扫描动画效果点击中间的黑色圆圈开始扫描动画,再次点击复位,需要这种效果的朋友可以自己下载看一下. 效果图如下所示: 这个界面相信大家都认识

  • Android仿微信、QQ附近好友雷达扫描效果

    1.概述 最近一直到在带实习生,因为人比较多,所以很长一段时间没有更新博客了,今天更新一篇雷达扫描附近好友效果,以后尽量每周更新一篇,先看一下效果: 2.实现 1.效果分析 效果分为两个部分,一个是上半部分的自定义RadarView,还有就是下半部分的ViewPager,至于怎么做到缩放和背景虚化的效果大家可以去看看LazyViewPager这里不详细介绍,这里主要实现扫描效果部分. 2.扫描效果实现 2.1自定义RadarView在onDraw()方法中画六个圆圈,至于圆圈的半径是多少我们需要

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

    最近在做聊天功能的时候,有一个需求是仿照微信做@好友的功能,本来以为挺简单,但是做到这块的时候,发现和想象的有点不一样,什么整块删除,块可编辑,总之,加个@的功能很简单,但是要做和微信的一样还是费了一些功夫,下面是一个demo仅供参考,防止遗忘 先上个效果图 就是这么个功能 1. 分析需求 输入@跳转到联系人界面,选中一个或者多个好友返回到当前界面 按退格键删除整块内容 块内的内容可编辑,编辑完了之后将不附带@功能,只是单纯的文字 2. 开始编码 既然是文本输入首先继承EditText自定义一个

  • android仿微信好友列表功能

    android studio实现微信好友列表功能,注意有一个jar包我没有放上来,请大家到MainActivity中的那个网址里面下载即可,然后把pinyin4j-2.5.0.jar复制粘贴到项目的app/libs文件夹里面,然后clean项目就可以使用了 实现效果图: (1)在build.gradle中引用第三方的类库 compile 'com.android.support:recyclerview-v7:26.0.0-alpha1' compile files('libs/pinyin4j

  • Android仿微信滑动弹出编辑、删除菜单效果、增加下拉刷新功能

    如何为不同的list item呈现不同的菜单,本文实例就为大家介绍了Android仿微信或QQ滑动弹出编辑.删除菜单效果.增加下拉刷新等功能的实现,分享给大家供大家参考,具体内容如下 效果图: 1. 下载开源项目,并将其中的liberary导入到自己的项目中: 2. 使用SwipeMenuListView代替ListView,在页面中布局: <android.support.v4.widget.SwipeRefreshLayout android:id="@+id/swipeRefresh

  • Android仿微信标签功能

    微信中有对联系人添加标签的功能,如下图所示. 这里有三种状态的标签,分别的未选择,选中,编辑中,由于前两种标签不需要提供输入,所以用TextView实现即可,编辑中的标签用EditText来实现.而标签的形状就用Shape来实现. 在drawable下新建xml文件,这里先上Shape的xml文件. tag_normal.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android=

  • Android仿微信长按菜单效果

    本文实例为大家分享了Android仿微信长按菜单展示的具体代码,供大家参考,具体内容如下 FloatMenu A menu style pop-up window that mimics WeChat.仿微信的长按菜单. 效果如下 引入方法: Github地址:https://github.com/JavaNoober/FloatMenu dependencies { .... compile 'com.noober.floatmenu:common:1.0.2' } 使用说明 使用方法1: A

  • Android仿微信加号菜单模式

    在模仿微信过程中有一个加号菜单启动着实让我有点费心,因为我去掉了自带的标题栏,想通过OnCreateOptionMenu这段代码来实现传统的Menu显示显然是不可能了.所以在自定义创建的状态栏里添加了一个加号的ImageView,想通过监听ImageView的Onclick来触发Popumenu的创建.基本效果与微信相似,细节方面还需多多考究. 看具体代码如下: 1.监听之后创建Popumenu的java代码: menuView.setOnClickListener(new View.OnCli

  • Android 仿微信朋友圈点赞和评论弹出框功能

    贡献/下载源码:https://github.com/mmlovesyy/PopupWindowDemo 本文简单模仿微信朋友圈的点赞和评论弹出框,布局等细节请忽略,着重实现弹出框.发评论,及弹出位置的控制. 1. 微信弹出框 微信朋友圈的点赞和评论功能,有2个组成部分: 点击左下角的"更多"按钮,弹出对话框: 点击评论,弹出输入框,添加评论并在页面中实时显示: 微信朋友圈点赞和评论功能 2. 实际效果 本文将建一个 ListView,在其 Item 中简单模仿微信的布局,然后着重实现

  • android 仿微信demo——登录功能实现(移动端)

    移动端登录功能实现 登录功能基本和注册一样,唯一不同的是登录可以实现两种登录方式(微信号和手机号),也就是布局不一样.所以需要两个布局,两个activity(这个方法比较简单粗暴,我懒.也可以通过activity动态切换布局,这样只需要一个activity就可以了) 创建两个activity,实现两种登录方式 微信号登录activity LoginUser.java package com.example.wxchatdemo; import android.annotation.Suppres

  • Android仿微信支付密码弹出层功能

    预览 使用 这个弹出层是一个DialogFragment,逻辑都封装在其内部,使用起来很简单: Bundle bundle = new Bundle(); bundle.putString(PayFragment.EXTRA_CONTENT, "提现:¥ " + 100.00); PayFragment fragment = new PayFragment(); fragment.setArguments(bundle); fragment.setPaySuccessCallBack(

  • Android 仿微信图像拍摄和选择界面功能(代码分享)

    插件运行后的画面如下: 下面这张图对图像进行筛选,根据照片产生的源头分(QQ和微信和相机) 点击某文件夹后,可以查看该文件夹下包含的所有的图片 图片选择界面 选中后就跳到已经选择界面的窗口,并且可以对该吃图片上传进行简要的描述 首先我想说明的是这个插件默认是不进行图片筛选的,打开app后会有几十个文件夹,但是个人认为开发中常用的图片基本都来自于QQ中拍摄的照片,微信中拍摄的照片,以及相机直接拍摄的照片,因此我对这个插件进行过滤以及文件夹名称的更改,具体做法,主要是对AlbumHelper类bui

随机推荐