![](https://img.haomeiwen.com/i19711046/47946e7ad9853f50.png)
最近项目中新增的一个页面中,Textview文本需要实现上图效果,特此记录。
参考资料: http://blog.csdn.net/industriously/article/details/53493392
为了实现上述效果,用一个Textview比较好实现。若由多个Textview拼接在布局中,在最后的Texiview换行时,第二行无法从头开始显示文本(如果有相关思路,请在评论区交流)。让一个Textview显示多样的文本,可以用SpannableString类实现。但是常用的场景只是改变文字的颜色以及增加相关文字的点击事件,若要实现上诉效果,我们需要重写ReplacementSpan类:
public class RadiusBackgroundSpan extends ReplacementSpan {
private int mSize;
private int mColor;
private int mRadius;
private Context mContext;
/**
* @param color 背景颜色
* @param radius 圆角半径
*/
public RadiusBackgroundSpan(int color, int radius,Context context) {
mColor = color;
mRadius = radius;
mContext = context;
}
@Override
public int getSize(Paint paint, CharSequence text, int start, int end, Paint.FontMetricsInt fm) {
mSize = (int) (paint.measureText(text, start, end) + 2 * mRadius +25);
//mSize就是span的宽度,span有多宽,开发者可以在这里随便定义规则
//我的规则:这里text传入的是SpannableString,start,end对应setSpan方法相关参数
//可以根据传入起始截至位置获得截取文字的宽度,最后加上左右两个圆角的半径得到span宽度
return mSize;
}
@Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, Paint paint) {
int color = paint.getColor();//保存文字颜色
paint.setColor(mColor);//设置背景颜色
paint.setAntiAlias(true);// 设置画笔的锯齿效果
RectF oval = new RectF(x, y + paint.ascent(), x + mSize, y + paint.descent());
//设置文字背景矩形,x为span其实左上角相对整个TextView的x值,y为span左上角相对整个View的y值。paint.ascent()获得文字上边缘,paint.descent()获得文字下边缘
canvas.drawRoundRect(oval, mRadius, mRadius, paint);//绘制圆角矩形,第二个参数是x半径,第三个参数是y半径
paint.setColor(mContext.getResources().getColor(R.color.white));//恢复画笔的文字颜色
canvas.drawText(text, start, end, x + mRadius, y, paint);//绘制文字
//添加文字右侧的图片
Bitmap bitmap = BitmapFactory.decodeResource( mContext.getResources(),R.drawable.icon_arrow_down);
//drawBitmap方法第二、第三个参数分别代表图案距TextView左侧距离,以及距TextView上边框距离。
canvas.drawBitmap(bitmap, x+mSize-40, 10, paint);
}
}
在Activity或Fragment中:
int radiusColor = getResources().getColor(R.color.orange_ff);
String content = "喂,您好!欧阳先生在忙,您找TA有什么事?";
SpannableString spanString = new SpannableString(content);
int start = content.indexOf("欧阳先生");
int end = start + "欧阳先生".length();
spanString.setSpan(new RadiusBackgroundSpan(radiusColor, 25,SettingCallNameActivity.this),start, end, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
//给"欧阳先生"添加点击事件
spanString.setSpan(new ClickableSpan() {
@Override
public void onClick(View view) {
//点击事件
}
@Override
public void updateDrawState(TextPaint ds) {
ds.setUnderlineText(false); //取消下划线
}
}, start, end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
mTvCallName.setText(spanString);
mTvCallName.setMovementMethod(LinkMovementMethod.getInstance());
网友评论