Android TextView中图文混排设置行间距导致高度不一致问题解决
最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse。。。什么鬼,之前明明测试过图文混排,不存在这个问题啊,然后检查代码,没毛病啊,
android:gravity="center_vertical" 也设置了啊,然后猛然发现一行代码:android:lineSpacingExtra="8sp",原来是设置了这个行间距导致的。知道问题出在哪了,就好解决了,度娘还是看源码,都OK的啊。
先贴一下对比图
解决之前的效果图:
解决之后的效果图:
图文混排,不可缺少:SpannableString和ImageSpan,但是阅读源码发现,ImageSpan设置对齐方式只有两种:
/**
* A constant indicating that the bottom of this span should be aligned
* with the bottom of the surrounding text, i.e., at the same level as the
* lowest descender in the text.
*/
public static final int ALIGN_BOTTOM = 0; /**
* A constant indicating that the bottom of this span should be aligned
* with the baseline of the surrounding text.
*/
public static final int ALIGN_BASELINE = 1;
要是ImageSpan能提供一个使其内容垂直居中的,问题不就轻松解决了吗,但是它没有提供了,****,再看,源码
ImageSpan是继承DynamicDrawableSpan的,而DynamicDrawableSpan中有两个这样的方法:getSize和draw,
@Override
public int getSize(Paint paint, CharSequence text,
int start, int end,
Paint.FontMetricsInt fm) {
Drawable d = getCachedDrawable();
Rect rect = d.getBounds(); if (fm != null) {
fm.ascent = -rect.bottom;
fm.descent = 0; fm.top = fm.ascent;
fm.bottom = 0;
} return rect.right;
}
@Override
public void draw(Canvas canvas, CharSequence text,
int start, int end, float x,
int top, int y, int bottom, Paint paint) {
Drawable b = getCachedDrawable();
canvas.save(); int transY = bottom - b.getBounds().bottom;
if (mVerticalAlignment == ALIGN_BASELINE) {
transY -= paint.getFontMetricsInt().descent;
} canvas.translate(x, transY);
b.draw(canvas);
canvas.restore();
}
所以我们也可以自定义去实现,最后贴上代码:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.style.ImageSpan; import java.lang.ref.WeakReference; /**
* @Created SiberiaDante
* @Describe:
* @Time: 2017/8/18
* @Email: 994537867@qq.com
* @GitHub: https://github.com/SiberiaDante
*/ public class CenterAlignImageSpan extends ImageSpan { private WeakReference<Drawable> mDrawableRef; public CenterAlignImageSpan(Context context, Bitmap bitmap, int verticalAlignment) {
super(context, bitmap, verticalAlignment);
} public CenterAlignImageSpan(Context context, int resId, int verticalAlignment) {
super(context, resId, verticalAlignment);
} @Override
public int getSize(Paint paint, CharSequence text, int start, int end,
Paint.FontMetricsInt fontMetricsInt) {
Drawable drawable = getDrawable();
Rect rect = drawable.getBounds();
if (fontMetricsInt != null) {
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.descent - fmPaint.ascent;
int drHeight = rect.bottom - rect.top;
int centerY = fmPaint.ascent + fontHeight / 2; fontMetricsInt.ascent = centerY - drHeight / 2;
fontMetricsInt.top = fontMetricsInt.ascent;
fontMetricsInt.bottom = centerY + drHeight / 2;
fontMetricsInt.descent = fontMetricsInt.bottom;
}
return rect.right;
} @Override
public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
int bottom, Paint paint) {
Drawable drawable = getCachedDrawable();
canvas.save();
Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
int fontHeight = fmPaint.descent - fmPaint.ascent;
int centerY = y + fmPaint.descent - fontHeight / 2;
int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;
canvas.translate(x, transY);
drawable.draw(canvas);
canvas.restore();
} private Drawable getCachedDrawable() {
WeakReference<Drawable> wr = mDrawableRef;
Drawable d = null;
if (wr != null) {
d = wr.get();
} if (d == null) {
d = getDrawable();
mDrawableRef = new WeakReference<>(d);
} return d;
}
}
最后:
SpannableString spannableStringCustom = new SpannableString("测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排");
CenterAlignImageSpan span = new CenterAlignImageSpan(this, R.mipmap.ic_launcher, ImageSpan.ALIGN_BASELINE);//重写的ImageSpan
spannableStringCustom.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textViewCustom.setText(spannableStringCustom);
参考文章:https://segmentfault.com/a/1190000007133405
Android TextView中图文混排设置行间距导致高度不一致问题解决的更多相关文章
- 【转】Android TextView SpannableStringBuilder 图文混排颜色斜体粗体下划线删除线
spannableStringBuilder 用法详解: SpannableString ss = new SpannableString("红色打电话斜体删除线绿色下划线图片:." ...
- android:怎样在TextView实现图文混排
我们通常在TextView文本中设置文字.但是怎样设置图文混排呢? 我就在这里写一个样例 .我们须要用到一点简单的HTML知识 在TextView中预订了一些类似HTML的标签,通过标签能够使Text ...
- android开发 自定义图文混排控件
功能:图文混排,可自动缩放字体,如图: 单点触控使用的代码来自:http://blog.csdn.net/xiaanming/article/details/42833893 谢谢博主! 在该dem ...
- 使用android SpannableStringBuilder实现图文混排
项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...
- 使用android SpannableStringBuilder实现图文混排,看到许多其他
项目开发需要达到这种效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuY3lsb3ZlamF2YQ==/font/5a6L5L2T/fontsiz ...
- 【转】关于FLASH中图文混排聊天框的小结
原文链接 图文混排也是FLASH里一个很古老的话题了,我们不像美国佬那样游戏里面聊天框就是聊天框,全是文字干干净净,也不像日本人发明了并且频繁地使用颜文字.不管是做论坛.做游戏,必定要实现的一点就是带 ...
- iOS中 图文混排/自定义图文混排 作者:韩俊强
指示根视图:(准备几张图片,把label加载在window上) CustomLable *label = [[CustomLable alloc]initWithFrame:CGRectMake(0, ...
- CSS - 关于li中图文混排不能垂直居中的问题
图片和文字一起放在li标签下不能同时垂直居中 解决办法: 1.设置图片的position:absolute; 2.把文字加上span标签: span{ height:30px;line-heigh ...
- 自定义图文混排视图MyImageTextView
http://blog.csdn.net/xujunfeng000/article/details/36399339?utm_source=tuicool&utm_medium=referra ...
随机推荐
- Nescafe #29 NOIP模拟赛
Nescafe #29 NOIP模拟赛 不知道这种题发出来算不算侵权...毕竟有的题在$bz$上是权限题,但是在$vijos$似乎又有原题...如果这算是侵权的话请联系我,我会尽快删除,谢谢~ 今天开 ...
- CJOJ 【DP合集】最长上升序列2 — LIS2
题面 已知一个 1 ∼ N 的排列的最长上升子序列长度为 K ,求合法的排列个数. 好题(除了我想不出来我应该找不到缺点), 想一想最长上升子序列的二分做法, 接在序列后面或者替换. 所以对于每一个位 ...
- layui 弹出层监听 判断弹出框的大小
if ($.PublicIsMobile($(window).width())) { var layerInitWidth = $("#layui-layer" + ly_dtxm ...
- Spring(十六)之MVC框架
MVC 框架教程 Spring web MVC 框架提供了模型-视图-控制的体系结构和可以用来开发灵活.松散耦合的 web 应用程序的组件.MVC 模式导致了应用程序的不同方面(输入逻辑.业 ...
- 模拟T1数字number
那么第一题首先非常水的一道题…… 看一下题 数字(number) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK拥有n个数,这n个数分别是a1,a2,… ...
- DB2创建视图view
create view v_table1(col1,col2,col3...)--视图名(字段一,字段二,字段三...) as --后跟查询语句 select col1,col2,col3... fr ...
- 利用WebHook实现PHP自动部署Git代码
平时项目代码都托管在Coding,然后每次提交了代码之后都要SSH到服务器上去git pull一次,很是繁琐,在看了OverTrue的<使用PHP脚本远程部署git项目>后就尝试在自己服务 ...
- mysql,int(5)、int(10)啥区别联系
实际没啥区别..这个5和10并不是最大5位,最大10位的意思. 好比选择了int(5),并且当你选择了0填充的话.你的数据假设存了123,那么你的显示会是00123,(有些操作mysql的工具看不出来 ...
- 基于Docker一键部署大规模Hadoop集群及设计思路
一.背景: 随着互联网的发展.互联网用户的增加,互联网中的数据也急剧膨胀.每天产生的数据量数以万计,本地文件系统和单机CPU已无法满足存储和计算要求.Hadoop分布式文件系统(HDFS)是海量数据存 ...
- 带你看懂大数据采集引擎之Flume&采集目录中的日志
一.Flume的介绍: Flume由Cloudera公司开发,是一种提供高可用.高可靠.分布式海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于采集数据:同时,flum ...