博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TextView图文混排
阅读量:6363 次
发布时间:2019-06-23

本文共 3240 字,大约阅读时间需要 10 分钟。

大家都知道,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, 0, tvDrawable.getMinimumWidth(), tvDrawable.getMinimumHeight());

3、构建ImageSpan 对象

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

 4、设置给上面的SpannableString对象

spanString.setSpan(span, 0, 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, int start, int end, 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, CharSequence text, int start, 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/8653246.html

你可能感兴趣的文章
标准C++实现任务队列
查看>>
jdbc url
查看>>
刷leetcode第704题-二分查找
查看>>
debug_backtrace() 函数生成一个 backtrace(追踪)
查看>>
第七天,还是盒子
查看>>
XAMPP软件包下载
查看>>
XXL-JOB初体验-ORACLE版
查看>>
沉思录:别人的棺材
查看>>
jersey + spring + mybatis + redis项目搭建
查看>>
PAT 1006 部分正确_另一种解法
查看>>
在Keil环境下使用JLink实现printf输出重定向至debug窗口
查看>>
JFreeChart生成3D饼图
查看>>
postgres的\d命令不显示全部的用户表
查看>>
poj 3468 A Simple Problem with Integers
查看>>
OOA/OOD/OOP细讲
查看>>
Tomcat 系统架构与设计模式_ 设计模式分析
查看>>
Confluence 6 计划你的升级
查看>>
本地串口TCP/IP 映射到远端串口
查看>>
通过git将php项目部署到LeanCloud
查看>>
Web开发之分页算法,N(N>=3)种解决方案
查看>>