Android—TextView中使用SpannableStringBuilder在末尾添加ImageSpan 导致Icon被截取或显示不全处理。
问题示例如下:
网上查看了些解决办法,如:TextView.setText(textStr,TextView.BufferType.SPANNABLE),此处理方法使用后,虽然没被截取了,也顺利显示了省略号,但是icon没有正常显示,宣告失败!
之后转变思路一想,能不能截取所需要的文字内容长度后,留出省略号和icon的位置,再添加icon?然后寻找思路,发现TextView有些方法可以使用:
显示用了几行:TextView.getLayout().getLineCount()
省略了多少字符:TextView.getLayout().getEllipsisCount(int line)
等等.......................就它了~
在使用中,你会发现,如果直接用textview去拿getLayout()这些数据,会拿不到。因为textview可能还没有被测量出来。
好了,大冬天,冷手,少写点说明,准备贴代码......................
(不好意思~没有代码)————>>>>>>>>
在activity中,或者adapter中:
String titleStr ="哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈快乐" ;
mTitleTextView.setText(Utils.setSpanIconWithTextView(titleStr,R.drawable.icon_ring_baoyue03, false));
mTitleTextView.post(newRunnable() {
@Override
public voidrun() {
Layout textViewLayout =mTitleTextView.getLayout();
int lines =textViewLayout.getLineCount();//获取显示展示的行数
int ellipsisCount =textViewLayout.getEllipsisCount(lines -1);//被省略的字符数
if (ellipsisCount >0) {//大于0表示被省略了,0表示全部展示。
int length =mTitleTextView.getText().length();//整个字符串长度
int subStrEnd =length -ellipsisCount;//显示出来的字符串长度(用于截取的坐标)
String text =mTitleTextView.getText().subSequence(0, subStrEnd -2) +"…";//截取并添加省略号(注意边界值,刚好为0的情况下)
mTitleTextView.setText(Utils.setSpanIconWithTextView(text,R.drawable.icon_ring_baoyue03, false));//重新在截取的字符上添加icon
}}});
注意代码第二句,先将要展示的内容给填充上。(1)前面提到的无法获取的问题。(2)便于后面处理边界值和不需要添加省略号的情况。也就是后面只有if没有else处理的情况,先加入内容,ellipsisCount >0的情况下,必然是需要添加省略号的。内容先加入,ellipsisCount=0,表示已经不需要处理了。
Utils如下:
public class Utils {
public static SpannableStringBuilder setSpanIconWithTextView(String strContent, in tresourceId, booleanisFront) {
if (resourceId ==0) {
return new SpannableStringBuilder(strContent);
} else {
if (strContent == null) {//不判字符串“”空,为了没文字的时候也能显示标签,避免nullstrContent ="";}
strContent =isFront ?" " + strContent : strContent +" ";
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(strContent);
Drawable drawable =MyApplication.getInstance().getResources().getDrawable(resourceId);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
CenterImageSpan span = new CenterImageSpan(drawable);
stringBuilder.setSpan(span, isFront ?0 : strContent.length() -1, isFront ?1 : strContent.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
return stringBuilder;
}}}
CenterImageSpan 如下:(icon能垂直居中显示)
public class CenterImageSpan extends ImageSpan {
public CenterImageSpan(Drawable drawable) {super(drawable); }
public CenterImageSpan(Bitmap bitmap) {super(bitmap); }
@Override
public void draw(@NonNull Canvas canvas, CharSequencetext, 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();
}}
此处理方法,好处在于不用自定义TextView,xml布局里面不用特殊设置TextView,支持设置:android:ellipsize="end" android:maxLines="2" 等属性。
如有问题,欢迎大家指出~~