最近项目中需要实现一个评论带表情的功能,刚开始一切顺利,非常easy,突然有一天发现文字跟表情混排的时候,TextView中图文高度不一致,excuse。。。什么鬼,之前明明测试过图文混排,不存在这个问题啊,然后检查代码,没毛病啊,

  1. android:gravity="center_vertical" 也设置了啊,然后猛然发现一行代码:android:lineSpacingExtra="8sp",原来是设置了这个行间距导致的。知道问题出在哪了,就好解决了,度娘还是看源码,都OK的啊。
    先贴一下对比图

 解决之前的效果图:

  

解决之后的效果图:  

  1.  
  2. 图文混排,不可缺少:SpannableStringImageSpan,但是阅读源码发现,ImageSpan设置对齐方式只有两种:
  1. /**
  2. * A constant indicating that the bottom of this span should be aligned
  3. * with the bottom of the surrounding text, i.e., at the same level as the
  4. * lowest descender in the text.
  5. */
  6. public static final int ALIGN_BOTTOM = 0;
  7.  
  8. /**
  9. * A constant indicating that the bottom of this span should be aligned
  10. * with the baseline of the surrounding text.
  11. */
  12. public static final int ALIGN_BASELINE = 1;

要是ImageSpan能提供一个使其内容垂直居中的,问题不就轻松解决了吗,但是它没有提供了,****,再看,源码

ImageSpan是继承DynamicDrawableSpan的,而DynamicDrawableSpan中有两个这样的方法:getSize和draw,

  1. @Override
  2. public int getSize(Paint paint, CharSequence text,
  3. int start, int end,
  4. Paint.FontMetricsInt fm) {
  5. Drawable d = getCachedDrawable();
  6. Rect rect = d.getBounds();
  7.  
  8. if (fm != null) {
  9. fm.ascent = -rect.bottom;
  10. fm.descent = 0;
  11.  
  12. fm.top = fm.ascent;
  13. fm.bottom = 0;
  14. }
  15.  
  16. return rect.right;
  17. }
  1. @Override
  2. public void draw(Canvas canvas, CharSequence text,
  3. int start, int end, float x,
  4. int top, int y, int bottom, Paint paint) {
  5. Drawable b = getCachedDrawable();
  6. canvas.save();
  7.  
  8. int transY = bottom - b.getBounds().bottom;
  9. if (mVerticalAlignment == ALIGN_BASELINE) {
  10. transY -= paint.getFontMetricsInt().descent;
  11. }
  12.  
  13. canvas.translate(x, transY);
  14. b.draw(canvas);
  15. canvas.restore();
  16. }

所以我们也可以自定义去实现,最后贴上代码:

  1. import android.content.Context;
  2. import android.graphics.Bitmap;
  3. import android.graphics.Canvas;
  4. import android.graphics.Paint;
  5. import android.graphics.Rect;
  6. import android.graphics.drawable.Drawable;
  7. import android.text.style.ImageSpan;
  8.  
  9. import java.lang.ref.WeakReference;
  10.  
  11. /**
  12. * @Created SiberiaDante
  13. * @Describe:
  14. * @Time: 2017/8/18
  15. * @Email: 994537867@qq.com
  16. * @GitHub: https://github.com/SiberiaDante
  17. */
  18.  
  19. public class CenterAlignImageSpan extends ImageSpan {
  20.  
  21. private WeakReference<Drawable> mDrawableRef;
  22.  
  23. public CenterAlignImageSpan(Context context, Bitmap bitmap, int verticalAlignment) {
  24. super(context, bitmap, verticalAlignment);
  25. }
  26.  
  27. public CenterAlignImageSpan(Context context, int resId, int verticalAlignment) {
  28. super(context, resId, verticalAlignment);
  29. }
  30.  
  31. @Override
  32. public int getSize(Paint paint, CharSequence text, int start, int end,
  33. Paint.FontMetricsInt fontMetricsInt) {
  34. Drawable drawable = getDrawable();
  35. Rect rect = drawable.getBounds();
  36. if (fontMetricsInt != null) {
  37. Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
  38. int fontHeight = fmPaint.descent - fmPaint.ascent;
  39. int drHeight = rect.bottom - rect.top;
  40. int centerY = fmPaint.ascent + fontHeight / 2;
  41.  
  42. fontMetricsInt.ascent = centerY - drHeight / 2;
  43. fontMetricsInt.top = fontMetricsInt.ascent;
  44. fontMetricsInt.bottom = centerY + drHeight / 2;
  45. fontMetricsInt.descent = fontMetricsInt.bottom;
  46. }
  47. return rect.right;
  48. }
  49.  
  50. @Override
  51. public void draw(Canvas canvas, CharSequence text, int start, int end, float x, int top, int y,
  52. int bottom, Paint paint) {
  53. Drawable drawable = getCachedDrawable();
  54. canvas.save();
  55. Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();
  56. int fontHeight = fmPaint.descent - fmPaint.ascent;
  57. int centerY = y + fmPaint.descent - fontHeight / 2;
  58. int transY = centerY - (drawable.getBounds().bottom - drawable.getBounds().top) / 2;
  59. canvas.translate(x, transY);
  60. drawable.draw(canvas);
  61. canvas.restore();
  62. }
  63.  
  64. private Drawable getCachedDrawable() {
  65. WeakReference<Drawable> wr = mDrawableRef;
  66. Drawable d = null;
  67. if (wr != null) {
  68. d = wr.get();
  69. }
  70.  
  71. if (d == null) {
  72. d = getDrawable();
  73. mDrawableRef = new WeakReference<>(d);
  74. }
  75.  
  76. return d;
  77. }
  78. }

最后:

  1. SpannableString spannableStringCustom = new SpannableString("测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排测试图文混排");
  2. CenterAlignImageSpan span = new CenterAlignImageSpan(this, R.mipmap.ic_launcher, ImageSpan.ALIGN_BASELINE);//重写的ImageSpan
  3. spannableStringCustom.setSpan(span, 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  4. textViewCustom.setText(spannableStringCustom);

参考文章:https://segmentfault.com/a/1190000007133405

Android TextView中图文混排设置行间距导致高度不一致问题解决的更多相关文章

  1. 【转】Android TextView SpannableStringBuilder 图文混排颜色斜体粗体下划线删除线

    spannableStringBuilder 用法详解: SpannableString ss = new SpannableString("红色打电话斜体删除线绿色下划线图片:." ...

  2. android:怎样在TextView实现图文混排

    我们通常在TextView文本中设置文字.但是怎样设置图文混排呢? 我就在这里写一个样例 .我们须要用到一点简单的HTML知识 在TextView中预订了一些类似HTML的标签,通过标签能够使Text ...

  3. android开发 自定义图文混排控件

    功能:图文混排,可自动缩放字体,如图: 单点触控使用的代码来自:http://blog.csdn.net/xiaanming/article/details/42833893  谢谢博主! 在该dem ...

  4. 使用android SpannableStringBuilder实现图文混排

    项目开发中需要实现这种效果 多余两行,两行最后是省略号,省略号后面是下拉更多 之前用过的是Html.fromHtml去处理图文混排的,仅仅是文字后图片或者文字颜色字体什么的, 但是这里需要在最后文字的 ...

  5. 使用android SpannableStringBuilder实现图文混排,看到许多其他

    项目开发需要达到这种效果 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmFuY3lsb3ZlamF2YQ==/font/5a6L5L2T/fontsiz ...

  6. 【转】关于FLASH中图文混排聊天框的小结

    原文链接 图文混排也是FLASH里一个很古老的话题了,我们不像美国佬那样游戏里面聊天框就是聊天框,全是文字干干净净,也不像日本人发明了并且频繁地使用颜文字.不管是做论坛.做游戏,必定要实现的一点就是带 ...

  7. iOS中 图文混排/自定义图文混排 作者:韩俊强

    指示根视图:(准备几张图片,把label加载在window上) CustomLable *label = [[CustomLable alloc]initWithFrame:CGRectMake(0, ...

  8. CSS - 关于li中图文混排不能垂直居中的问题

    图片和文字一起放在li标签下不能同时垂直居中   解决办法: 1.设置图片的position:absolute; 2.把文字加上span标签: span{ height:30px;line-heigh ...

  9. 自定义图文混排视图MyImageTextView

    http://blog.csdn.net/xujunfeng000/article/details/36399339?utm_source=tuicool&utm_medium=referra ...

随机推荐

  1. 【转】ios tableView那些事(一)创建一个简单的tableView

    工作也有半年多了!几乎每个项目中的会用到tableview这个神奇而好用的控件,在学习和工作中都会看别人的博客!对我有很大的帮助,就如同站在巨人的肩膀上的感觉吧 哈哈!于是决定重新开始写博客,希望能帮 ...

  2. 连接远程数据库ORACLE11g,错误百出!

    客户机中PLSQL DEV访问虚拟机中的ORACLE11g,错误百出! 创建时间: 2017/10/14 18:44 作者: CNSIMO 标签: ORACLE 忙了一下午,只有两个字形容:麻烦!   ...

  3. Node.js实战(四)之调试Node.js

    当项目逐渐扩大以后,功能越来越多,这时有的时候需要增加或者修改,同时优化某些功能,就有可能出问题了.针对于线上Linux环境我们应该如何调试项目呢? 别怕,Node.js已经为我们考虑到了. 通过 n ...

  4. 浅谈 DNS

    一.DNS(Domain Name System,域名系统) 概念:万维网(WWW是环球信息网的缩写,亦作“Web”.“WWW”.“'W3'”,英文全称为“World Wide Web”),作为域名和 ...

  5. Android 关于Activity的四种启动模式的简单介绍

    Activity启动模式设置: <activity android:name=".MainActivity" android:launchMode="standar ...

  6. 大页内存(HugePages)

    原文转载自:http://blog.csdn.net/yutianzuijin/article/details/41912871 今天给大家介绍一种比较新奇的程序性能优化方法—大页内存(HugePag ...

  7. 详细解读大数据分析引擎Pig&PigLatin语句

    Pig 一.Pig的介绍: Pig由Yahoo开发,主要应用于数据分析,Twitter公司大量使用Pig处理海量数据,Pig之所以是数据分析引擎,是因为Pig相当于一个翻译器,将PigLatin语句翻 ...

  8. 20155235 《网络攻防》 实验八 Web基础

    20155235 <网络攻防> 实验八 Web基础 实验内容 Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与POST方法,编写一个含有表 ...

  9. 20155311 Exp3 免杀原理与实践

    20155311 Exp3 免杀原理与实践 •免杀 一般是对恶意软件做处理,让它不被杀毒软件所检测.也是渗透测试中需要使用到的技术. [基础问题回答] (1)杀软是如何检测出恶意代码的? 1.通过特征 ...

  10. asp.net mvc2+nhibernate实体类映射问题之“尝试创建Controller类型的控制器时出错请确保控制器具有无参数公共构造函数”

    程序出了问题,解决后发现如此简单,犯的错误是如此的低级啊,特此记录! 运行程序总是在浏览器中看到一片空白,什么也没有,用application_error跟踪发现抓出一个这样的异常 然后浏览器中就是这 ...