加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

TextView图文混排

发布时间:2020-12-16 23:41:21 所属栏目:百科 来源:网络整理
导读:大家都知道,textView有一个setCompoundDrawables的方法来设置上下左右位置的图标,当然,也可以在xml布局文件中设置,然而问题来了,假如我们把图标放在左边,当我们让TextView分多行显示的时候,会出现一种情况,左边的图标并不会与第一行对齐,而是与整个

大家都知道,textView有一个setCompoundDrawables的方法来设置上下左右位置的图标,当然,也可以在xml布局文件中设置,然而问题来了,假如我们把图标放在左边,当我们让TextView分多行显示的时候,会出现一种情况,左边的图标并不会与第一行对齐,而是与整个textView居中对齐。

即我们要的是下图:

结果是这个图:

怎么办呢?我们可以用图文混排:

我们可以利用SpannableString和ImageSpan。

1、构建SpannableString对象。

SpannableString spanString = new SpannableString(textView.getText().toString());

2、获取Drawable对象,即将我们的图案转换为Drawable对象,并设置大小。

Drawable tvDrawable = ContextCompat.getDrawable(mContext,R.drawable.pic); tvDrawable.setBounds(0,tvDrawable.getMinimumWidth(),tvDrawable.getMinimumHeight());

3、构建ImageSpan 对象

ImageSpan span = new ImageSpan(tvDrawable,ImageSpan.ALIGN_BASELINE);

?4、设置给上面的SpannableString对象

spanString.setSpan(span,1,Spannable.SPAN_INCLUSIVE_EXCLUSIVE);

5、最终设置给TextView

textView.setText(spanString)

?

加下来讲讲上面的方法:

1、ImageSpan对象,第二个参数为图像与文字的对齐方式,ImageSpan只带有两个对齐方式,分别是:ALIGN_BASELINE、ALIGN_BOTTOM。

ALIGN_BOTTOM?表示与文字内容的底部对齐,如果在构造ImageSpan时没有传入对齐方式,那么默认就是这种底部对齐。

ALIGN_BASELINE,表示与文字内容的基线对齐

ImageSpan Span = new ImageSpan(tvDrawable,ImageSpan.ALIGN_BASELINE);

2、setSpan()方法

public void setSpan(Object what,int start,int end,int flags) { super.setSpan(what,start,end,flags); }

what传入各种Span类型的实例;?
startend标记要替代的文字内容的范围;?
flags是用来标识在Span范围内的文本前后输入新的字符时是否把它们也应用这个效果,它有如下几个:

Spanned.SPAN_EXCLUSIVE_EXCLUSIVE、

Spanned.SPAN_INCLUSIVE_EXCLUSIVE、

Spanned.SPAN_EXCLUSIVE_INCLUSIVE、

Spanned.SPAN_INCLUSIVE_INCLUSIVE

INCLUSIVE表示应用该效果,EXCLUSIVE表示不应用该效果,如Spanned.SPAN_INCLUSIVE_EXCLUSIVE表示对前面的文字应用该效果,而对后面的文字不应用该效果。

?

坑:

1、既然ImageSpan只带有两个对齐方式,那我们需要自己实现居中对齐:

class MyImageSpan extends ImageSpan { public static final int ALIGN_CENTER = 2; public MyImageSpan(Drawable d,int verticalAlignment) { super(d,verticalAlignment); } @Override public void draw(Canvas canvas,CharSequence text,float x,int top,int y,int bottom,Paint paint) { Drawable b = getDrawable(); canvas.save(); Paint.FontMetricsInt fm = paint.getFontMetricsInt(); //系统默认为ALIGN_BOTTOM
            int transY = bottom - b.getBounds().bottom; if (mVerticalAlignment == ALIGN_BASELINE) { transY -= fm.descent; } else { transY = ((y + fm.descent + y + fm.ascent) / 2
                        - b.getBounds().bottom / 2); } canvas.translate(x,transY); b.draw(canvas); canvas.restore(); } @Override public int getSize(Paint paint,int end,Paint.FontMetricsInt fm) { Drawable b = getDrawable(); Rect rect = b.getBounds(); if (fm != null) { Paint.FontMetricsInt painFm = paint.getFontMetricsInt(); int fontHeight = (painFm.bottom - painFm.top); int drHeight = rect.bottom - rect.top; int top = drHeight / 2 - fontHeight / 4; int bottom = drHeight / 2 + fontHeight / 4; fm.ascent = -bottom; fm.top = -bottom; fm.bottom = top; fm.descent = top; } return rect.right; } }

?为何上面的自定义能够实现居中对齐呢?首先要了解Paint.FontMetrics。

请看另一篇博客:https://www.cnblogs.com/tangZH/p/8692910.html

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读