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, 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类型的实例;
start和end标记要替代的文字内容的范围;
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/8692910.html
TextView图文混排的更多相关文章
- TextView + Spanned实现图文混排以及图片点击交互
最近要实现图文混排的需求,webview过大,所以想到了用SpannableStringBuilder来实现. 不过参考了大量国内文章,大多数是教你如何实现图文混排,并没有提及图片点击交互的.有翻阅了 ...
- Android 自绘TextView解决提前换行问题,支持图文混排
先看下效果图: 上面是MTextView,下面是默认的TextView. 一.原因 用最简单的全英文句子为例,如果有一个很长的单词,这一行剩余的空间显示不下了,那么规则就是不打断单词,而是把整个单词丢 ...
- Android TextView中图文混排设置行间距导致高度不一致问题解决
最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse...什么鬼,之前明明测试过图文混排,不存在这个 ...
- Android中Textview显示Html,图文混排,支持图片点击放大
本文首发于网易云社区 对于呈现Html文本来说,Android提供的Webview控件可以得到很好的效果,但使用Webview控件的弊端是效率相对比较低,对于呈现简单的html文本的话,杀鸡不必使用牛 ...
- android:怎样在TextView实现图文混排
我们通常在TextView文本中设置文字.但是怎样设置图文混排呢? 我就在这里写一个样例 .我们须要用到一点简单的HTML知识 在TextView中预订了一些类似HTML的标签,通过标签能够使Text ...
- 用NSAttributedString实现简单的图文混排
iOS7以后,因为TextKit的强大,可以用NSAttributedString很方便的实现图文混排(主要是利用了NSTextAttachment). 关于Textkit的牛逼之处,可以参考objc ...
- ListView异步加载图片,完美实现图文混排
昨天参加一个面试,面试官让当场写一个类似于新闻列表的页面,文本数据和图片都从网络上获取,想起我还没写过ListView异步加载图片并实现图文混排效果的文章,so,今天就来写一下,介绍一下经验. Lis ...
- UITextView实现图文混排效果
用UITextView实现图文混排效果的展示,首先要禁用UITextView的编辑功能,将属性editable设置为NO 1.首先创建一个NSTextAttachment对象,这个对象有一个image ...
- 使用android SpannableStringBuilder实现图文混排
项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...
随机推荐
- 数组Array和列表集合ArrayList、LinkedList和Vector的区别
一.ArrayList和Vector的区别 ArrayList与Vector主要从以下方面来说. 1.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同 ...
- [Swift]LeetCode667. 优美的排列 II | Beautiful Arrangement II
Given two integers n and k, you need to construct a list which contains n different positive integer ...
- [Swift]LeetCode1007. 行相等的最少多米诺旋转 | Minimum Domino Rotations For Equal Row
In a row of dominoes, A[i] and B[i] represent the top and bottom halves of the i-th domino. (A domi ...
- mybatis xml < >
[参考文章]:mybatis 中的 xml 配置文件中 ‘<’. ‘>’ 处理 1.使用转义字符将 ‘<’. ‘>’ 替换掉 描述 字符 转义字符小于号 < <大于 ...
- 文本编辑器激活系列(二):UltraEdit安装、激活、汉化教程
如您激活出现问题,请点击这里加入:软件激活问题解决群 前言 推荐几款文本编辑器: Sublime:内嵌python解释器.大量插件 EditPlus:语法着色.内嵌浏览器 Notepad++:所见即所 ...
- JVM基础系列开篇:为什么要学虚拟机?
跟许多人一样,我一开始接触 Java 虚拟机只是因为面试需要用到,所以硬着头皮看看.所以很多人对于为什么要学虚拟机这个问题,他们的答案都是:因为面试.但我经过了几年的学习和实战,我发现其实学习虚拟机并 ...
- C++11 实现生产者消费者模式
代码都类似,看懂一个,基本都能理解了. 共有代码: #include <cstdlib>#include <condition_variable>#include <io ...
- java基础(一)-----java的三大特性之封装
面向对象编程有三大特性:封装.继承.多态.本文将介绍java的三大特性之封装 封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成 ...
- mysql 架构篇系列 4 复制架构一主一从搭建(半同步复制)
一.概述 在mysql 5.5之前,mysql 的复制是异步操作,主库和从库的数据之间存在一定的延时,这样存在一个隐患:当主库上写入一个事务并提交成功,而从库尚未得到主库推送的Binlog日志时,主库 ...
- redis 系列6 数据结构之字典(下)
一.概述 接着上篇继续,这篇把数据结构之字典学习完, 这篇知识点包括:哈希算法,解决键冲突, rehash , 渐进式rehash,字典API. 1.1 哈希算法 当一个新的键值对 需要添加到字典里面 ...