仿头条艾特@用户名实现思路

首先第1步:

要实现输入@后跳转到用户列表页,最开始想到的是用addTextChangedListener监听用户输入内容,之后反应过来,这个方法监听的是edittext的内容,而不是输入内容。

所以要用InputFilter来实现,InputFilter对“每一次输入”进行一次过滤,若重写filter()返回null,则输入的文本不会被替换掉,而若filter()返回一个String,则所输入的内容将会被替换掉;

 1     private class MyInputFilter implements InputFilter {
 2         @Override
 3         public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
 4             LogUtil.e("AtEdittext输入了:",source.toString());
 5             if ((source.toString().equalsIgnoreCase("@") || source.toString().equalsIgnoreCase("@"))) {
 6                 LogUtil.e("AtEdittext", "输入了@");
 7                 if (onJumpListener != null) {
 8                     onJumpListener.goToChooseContact();
 9                 }
10             }else{
11                 int keep = mMax - (dest.length() - (dend - dstart));
12                 if (keep <= 0) {
13                     return "";
14                 } else if (keep >= end - start) {
15                     return null;
16                 } else {
17                     keep += start;
18                     if (Character.isHighSurrogate(source.charAt(keep - 1))) {
19                         --keep;
20                         if (keep == start) {
21                             return "";
22                         }
23                     }
24                     return source.subSequence(start, keep);
25                 }
26             }
27             return source;
28         }
29     }

第2步:

 实现“@用户名”高亮显示。在输入用户名之后,用正则表达式匹配“@用户名 ”,记录下需要高亮显示的起始位置和结束位置,最后为整段内容设置setSpan。

为了防止输入完成以后,在用户名中间插入任何字符,所以需要将文字转换转换成图片样式,这就用到DynamicDrawableSpan啦,可以将文字转换成图片样式,而且也可以实现删除整个用户名,不用每个字符挨个删除。

 1 public class LDSpan extends DynamicDrawableSpan {
 2     private Context context;
 3     private Bitmap bitmap;
 4 
 5     public LDSpan(Context context, UserInfoBean user) {
 6         this.context = context;
 7         this.bitmap = getNameBitmap(user.getAtUname());
 8     }
 9 
10     @Override
11     public Drawable getDrawable() {
12         BitmapDrawable drawable = new BitmapDrawable(context.getResources(), bitmap);
13         drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
14         return drawable;
15     }
16 
17 
18     /**
19      * 把返回的人名,转换成bitmap
24      */
25     private Bitmap getNameBitmap(String name) {
26         /* 把@相关的字符串转换成bitmap 然后使用DynamicDrawableSpan加入输入框中 */
27         Paint paint = new Paint();
28         paint.setAntiAlias(true);
29         //设置字体画笔的颜色
30         paint.setColor(context.getResources().getColor(R.color.bg_text_blue));
31         //设置字体的大小
32         paint.setTextSize(UnitSociax.dip2px(context, 15));
33         Rect rect = new Rect();
34         paint.getTextBounds(name, 0, name.length(), rect);
35         // 获取字符串在屏幕上的长度
36         int width = (int) (paint.measureText(name));
37         final Bitmap bmp = Bitmap.createBitmap(width, rect.height(), Bitmap.Config.ARGB_8888);
38         Canvas canvas = new Canvas(bmp);
39 //        canvas.drawColor(getResources().getColor(R.color.color_blue));
40         canvas.drawText(name, rect.left, rect.height() - rect.bottom, paint);
41         return bmp;
42     }
43 }

第3步:

  spannableString.setSpan(dynamicDrawableSpan, startIndex, endIndex, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);

By LiYing

原文地址:https://www.cnblogs.com/widgetbox/p/11912130.html