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仿微信@好友功能 输入@跳转、删除整块,希望对大家有所帮助