仿头条艾特@用户名实现思路
首先第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