类似该需求的一个实现方案
具体实现方法
1.布局文件就一个TextView就可以,无需自定义TextView
2.使用SpannableString
- 先设置最后一位空格成图标
val string=getString(R.string.address_content)//字符串最后加一个两个空格以便将其替换成图标。不然就会被图标占据内容
val spannableString=SpannableString(string)
val d = ContextCompat.getDrawable(this,R.mipmap.ic_copy)!!
d.setBounds(0, 0, d.minimumWidth, d.minimumHeight)
spannableString.setSpan(//先设置最后一位空格成图标
ImageSpan(d),
string.length-1,
string.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
这样设置出来假设图标高度比文字高就和文字不居中。
所以就需要自定义ImageSpan,重写draw方法,将其和文字垂直居中
public class VerticalImageSpan extends ImageSpan {
public VerticalImageSpan(Drawable drawable) {
super(drawable);
}
public VerticalImageSpan(Bitmap b) {
super(b);
}
@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom,
@NonNull Paint paint) {
Drawable b = getDrawable();
Paint.FontMetricsInt fm = paint.getFontMetricsInt();
int transY = (y + fm.descent + y + fm.ascent) / 2 - b.getBounds().bottom / 2;//计算y方向的位移
canvas.save();
canvas.translate(x, transY);//绘制图片位移一段距离
b.draw(canvas);
canvas.restore();
}
}
得到了正确的效果
- 再设空格和图标的点击事件 (也就是最后两位的点击事件)
spannableString需要再次setSpan
spannableString.setSpan(object : ClickableSpan(){//再设置后两位点击事件
override fun onClick(widget: View) {
//这里是点击事件
}
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.isUnderlineText = false//取消下划线
}
}, string.length-2, string.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
mTextview.text= spannableString
mTextview.movementMethod = LinkMovementMethod.getInstance()
注意必须设置LinkMovementMethod.getInstance()才会生效