ImageSpan类为TextView提供了图文混排的形式,在ImageSpan的构造函数中提供了一个参数 int verticalAlignment,表示垂直对齐方式,有两个参数 ALIGN_BASELINE、ALIGN_BOTTOM 分别为顶部、底部对齐,但是没有居中对齐的参数(其实会找到这篇文章的人应该知道这点了。。)

下面说说我的实现思路及方法

1.根据构造函数verticalAlignment参数找到影响对齐方式的代码

    public ImageSpan(Context context, int resourceId, int verticalAlignment) {super(verticalAlignment);mContext = context;mResourceId = resourceId;}

查看源码可知对齐参数是在ImageSpan的父类DynamicDrawableSpan中设置的

2.查看DynamicDrawableSpan类源码找出对齐方式的代码,在源码中能看到两个方法getSize与draw

3.getSize方法,返回一个Int含义为图片的宽度,但是我们看源码发现里面干的事情不仅是返回宽度还设置了文字的ascent、descent的位置

    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;}

4.draw方法,根据对齐参数绘制图片。所以第一步就是修改draw方法来实现居中

    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();}

5.修改draw方法

 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();int transY = 0;//获得将要显示的文本高度-图片高度除2等居中位置+top(换行情况)transY = ((bottom-top) - b.getBounds().bottom)/2+top;//偏移画布后开始绘制canvas.translate(x, transY);b.draw(canvas);canvas.restore();}

6.这时候如果运行调试的话会发现完全没效果。。为啥呢,别急还有一个重要方法没修改,那就是getSize方法,我们还需要修过getSize方法中对文字ascent、descent等参数的设置才行

 public int getSize(Paint paint, CharSequence text, int start, int end,FontMetricsInt fm) {Drawable d = getDrawable();Rect rect = d.getBounds();if (fm != null) {FontMetricsInt fmPaint=paint.getFontMetricsInt();//获得文字、图片高度int fontHeight = fmPaint.bottom - fmPaint.top;int drHeight=rect.bottom-rect.top;//对于这段算法LZ表示也不解,正常逻辑应该同draw中的计算一样但是显示的结果不居中,经过几次调试之后才发现这么算才会居中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;}

7.到这就完成了图文居中的功能,效果图

下面上完整源码,谢谢支持

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.FontMetricsInt;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.widget.TextView;public class MainActivity extends ActionBarActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);TextView textView=new TextView(this);setContentView(textView);SpannableString showString = new SpannableString("1234533333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333336");MyIm imageSpan=new MyIm(this, R.drawable.ic_launcher);MyIm imageSpan2=new MyIm(this, R.drawable.ic_launcher);MyIm imageSpan21=new MyIm(this, R.drawable.ic_launcher);showString.setSpan(imageSpan, 2, 3, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);showString.setSpan(imageSpan2, 27, 30, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);showString.setSpan(imageSpan21, 77, 78, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);textView.setText(showString);}public class MyIm extends ImageSpan{public MyIm(Context arg0,int arg1) {super(arg0, arg1);}public int getSize(Paint paint, CharSequence text, int start, int end,FontMetricsInt fm) {Drawable d = getDrawable();Rect rect = d.getBounds();if (fm != null) {FontMetricsInt fmPaint=paint.getFontMetricsInt();int fontHeight = fmPaint.bottom - fmPaint.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;}@Overridepublic 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();int transY = 0;transY = ((bottom-top) - b.getBounds().bottom)/2+top;canvas.translate(x, transY);b.draw(canvas);canvas.restore();}}
}

Android ImageSpan的图文居中对齐相关推荐

  1. android span图片居中,Android ImageSpan的图文居中对齐

    ImageSpan类为TextView提供了图文混排的形式,在ImageSpan的构造函数中提供了一个参数 int verticalAlignment,表示垂直对齐方式,有两个参数 ALIGN_BAS ...

  2. TextView 图文混排,图文居中对齐

    惯例:先上图后说话,谢谢各位伙伴的支持! 有你们是我的福分! 每日一言:做你害怕的事情,然后你会发现不过如此. 一.使用方法 TextView tvCustomImageSpan=(TextView) ...

  3. android相对控件居中对齐,相对布局(RelativeLayout)常用属性

    RelativeLayout子控件的一些属性: //相对于同级控件对齐方式 android:layout_alignBaseline     将该控件的baseline与给定ID的baseline对齐 ...

  4. Android中文图混排时文图的居中对齐 FontMetrics以及自定义ImageSpan实现

    文章转自:http://www.sohu.com/a/150059234_611601 本文作者CnPeng的博客地址: http://www.jianshu.com/p/2650357f7547 这 ...

  5. android中,实现水平方向上三个按钮左对齐、居中对齐、右对齐效果

    解析:使用FrameLayout 可以很容易解决这个问题, 方法一:View 的上.下.左.右.居中对齐是界面中经常接触到的布局效果.单独某种对齐方式有很多种写法.但同一个方向的各种对齐布局,Fram ...

  6. android动态设置文本居中显示图片,android按钮图片和文本居中的代码-你躺枪了吗...

    最近优化项目代码时,发现一个比较诡异的现象:每当界面进入ActivityA时,cpu在不断的消耗,内存在不断的缓慢增长(虽然每次增长的量非常小).如下图: 屏幕快照 2016-07-24 12.26. ...

  7. android 按钮 图片文字居中显示,[Android]Android 布局中如何让图片和文字居中显示?...

    图片文字居中显示 **①组件TextView的属性 drawableTop ``` 块内或者行内图片与文字居中对齐最靠谱的方式! 做图片与文字在一行的按钮时候最常用到,总结了一个靠谱的方法,终于可以完 ...

  8. RelativeLayout中控件居中对齐

    在当使用RelativeLayaout进行布局的时候,主要使用的是RelativeLayout控件是作为一个容器,在这个容器中加入相应的控件,但是若将这些空间居中对齐,我们一般使用的是android: ...

  9. html5 canvas 显示文字居中,html5 canvas 文字居中对齐

    > web前端 > HTML 5 > 正文 html5 canvas 文字居中对齐 2013-07-09 我要投稿 [color=eight:25px]html部门 [color=e ...

最新文章

  1. 程序员如何打造个人品牌?
  2. 发现一位大佬的算法刷题笔记PDF
  3. EasyDarwin开源音频解码项目EasyAudioDecoder:EasyPlayer Android音频解码库(第二部分,封装解码器接口)...
  4. 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)
  5. 文件查找工具everything的下载使用
  6. 抽屉之Tornado实战(5)--点赞与评论树
  7. Spring的Web MVC –重定向到内存泄漏
  8. 使用PostgREST的配置教程
  9. java long short_Java Long类shortValue()方法与示例
  10. 学习笔记(07):MySQL数据库运维与管理-02-用户权限授予演示
  11. 《剑指offer》面试题22——栈的压入、弹出序列(C++)
  12. 银行业会计人员技能训练系统(含文字录入、小键盘、点钞)
  13. 初学Linux的简单命令(一)
  14. linux安装红警教程,红警2任务安装教程_红色警戒2任务安装方法一览
  15. 华为一员工猝死出租屋 警方初步排除他杀
  16. 17-统一网关Gateway
  17. 搭建 Spring Cloud Alibaba 微服务框架
  18. android属于数据库管理系统,详细谈谈Android系统中的SQLite数据库的应用
  19. GlusterFS概述
  20. Bat命令学习-FOR参数F的选项delims与tokens

热门文章

  1. 使用云服务器创建网站(完整开发过程)
  2. 防御性驾驶技术全集详细技巧-什么是防御性驾驶
  3. 几种主流网页开发语言的思考(下)
  4. DevOps企业实践指南(8): 安全机制
  5. 元宇宙投融资火热 | 产业区块链发展周报
  6. UART驱动程序设计
  7. 隐函数和参数方程的二阶导数(新绿)
  8. ShopEx 模版标签
  9. 关于对国内360杀毒的一点原理剖析(看法)
  10. Qt Widgets、QML、Qt Quick 的区别