java xml textview居中_android—图文垂直居中 TextView+SpannableString

自我感觉做什么事情都是事倍功半,同样性格还是丢三落四的人。记录每一次解决问题的思路经过,以供自我学

6d90bf2ff7c7

最终效果

前几天让做一个效果如上图,于是引发了一些列的思路风暴:

(思路1)TextView+Html的形式:html在网页实现很常见的,所以不免第一个反应就是用html。于是让前端哥们写了一段html文本,但是当我用着个文本显示的时候发现没有效果,于是开始想是不是因为哥们用的CSS3.0,html5的原因(因为可能手机的TextView不支持,所以可能是这原因),然后去网上搜索看TextView都支持什么html标签,最后发现TextView支持有限的Html标签,其中知识一些简单的字体,颜色,背景,还不支持CSS(更不用说CSS3.0了)

思路1总结:整个过程耗费了半个下午,其中还包括1一个人情(前端哥们的帮忙) 。查询TextView具体支持标签在Html.from("")的方法中查找

知识点总结:TextView支持的html很是有限的,关于字体的样式还是用自个的标签。而且最后html会被转换span的形式

(思路2)ImageScpan+自定义drawable方式:textview+html不行,那么,只能用span。为什么使用ImageSpan原因:1,因为可以把“服务中”这个块当成图片。如果用ImageScpan实现了的话,后期可以随便换成任何图片。2。不使用ImageSpan的话,只能使用backgroundscpan,relativespan和字体颜色span等至少三个集合,有点多了感觉,最重要的是Imagespan是可以到行尾部换行了(解释:如果行尾的预留的宽度不够的话,会另起一行。所选文字对于一个图片块),不知道其他的行不行(解释:字面意思backgroundspan只是改变所选文章的背景色,所针对的文字还是一个对一个。另外两个span一样的)。使用imagespan+图片的形式是合理的选择,既然这个形式的话那么imagespan+自定义的drawable是最好的思路出现了,这里是因为自定义drawable可以绘制任何图片。于是要自个实现一个drawable和系统的imagespan组装这个效果。到这里以为终于可以了,走几步才发现,嘿嘿...

系统的Imagescpan不行,不能和文字垂直居中,并且当所使用图片高度大于文字的ascent(。好像是这个。 )时,改行的行高使用会加上一定高度。于是上网搜索垂直居中ImageScpan 。

思路2总结:整个过程进展也算合理。最后的结果是:搜索的垂直居中imagescpan+自定义drawable。(出错了,为什么不直接写一个自定义自个的Imagescpan呢)工作量相对多,自定义两个东西

知识点总结:

1,系统的Imagescpan不行,不能和文字垂直居中,并且当所使用图片高度大于文字的ascent(。好像是这个。 )时,改行的行高使用会加上一定高度。于是上网搜索垂直居中ImageScpan 。

2,牵扯到了drawable自定义 ,了解到当drawable.draw(canvas)之前 drawable.getbouds返回的区域必须是有个有空间的区域。不能是高为0,宽为0,这样的话只会看不到

3,中间搜索到了一个大神写的垂直居中的ImageSpan

(思路3) 自定义自个的ImageSpan:直接自定义自个的span,抛弃了思路2还用自个写自定义drawable,显然这个是不错的。直接朝这个方向前进吧!!最后完成了效果

思路3总结:canvas.drawline的时候水平线应该是字体的baseline的位置。

针对这个问题最终总结:

1, 是因为自个不知道textview支持多少html标签,所以有了思路1。途中得到的战果

TextView支持的html很是有限的,关于字体的样式还是用自个的标签。而且最后html会被转换span的形式

2, 为什么会出现思路2的情况,有两个需要自定义的类,是因为当时大脑乱纠结这个问题太长时间了。没想过直接二合一直接自定义一个 途中得到的战果

系统的Imagescpan不行,不能和文字垂直居中,并且当所使用图片高度大于文字的ascent(。好像是这个。 )时,改行的行高使用会加上一定高度。于是上网搜索垂直居中ImageScpan 。

牵扯到了drawable自定义 ,了解到当drawable.draw(canvas)之前 drawable.getbouds返回的区域必须是有个有空间的区域。不能是高为0,宽为0,这样的话只会看不到

中间搜索到了一个大神写的垂直居中的ImageSpan

在xml中设置textview的行高不会体现的设置字体高度(原以为会体现到字体 dscent ),只是体现到行与行之间的距离上

献上最后的两个重要的ImageSpan

网上搜索的某个大神:

public class VerticalImageSpan extends ImageSpan { //根据图片调整字体,来是适应图片的高度

public VerticalImageSpan(Context context,int drawableid) {

super(context,drawableid);

}

/**

* update the text line height

*/

@Override

public int getSize(Paint paint,CharSequence text, intstart, intend, Paint.FontMetricsInt fontMetricsInt) { //设置图片块的宽度

Drawable drawable = getDrawable();

Rect rect = drawable.getBounds(); //注意点,这个rect应该是有效的空间 高度为0,宽度为0 drawable就绘制不出来,在这个地方是用

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;

}

/**

* see detail message in android.text.TextLine

*

*@paramcanvasthe canvas, can be null if not rendering

*@paramtextthe text to be draw

*@paramstartthe text start position

*@paramendthe text end position

*@paramxthe edge of the replacement closest to the leading margin

*@paramtopthe top of the line //文本所在改行的顶部

*@paramythe baseline //文本的基准线

*@parambottomthe bottom of the line //文本所在改行的底部 及下行的顶部,xml文件中的设置的行间距会直接影响 bottom到baseline的距离

*@parampaintthe work paint

*/

@Override

public void draw(Canvas canvas,CharSequence text, int start, int end,

float x, int top, inty, int bottom,Paint paint) {

CharSequence targetText=text.subSequence(start,end);

Log.v("文字",targetText.toString());

Drawable drawable = getDrawable();

canvas.save();

Rect rect =drawable.getBounds(); //注意点,这个rect应该是有效的空间 高度为0,宽度为0 drawable就绘制不出来,

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int fontHeight = fmPaint.descent- fmPaint.ascent;

int centerY = y + fmPaint.descent- fontHeight /2;

int transY = centerY - (rect.bottom- rect.top) /2;

canvas.translate(x,transY);

drawable.draw(canvas);

canvas.restore();

}

}

这个是我最终的图文居中span,如下:

public class CustomSpan extends ImageSpan { //图片适应文本行高度

int resourceId;

int textColor;

float textRadio;

int marginH;//左右间隔

Rect rect;

Drawable drawable;

publicCustomSpan(Context context, int resourceId, int textColor, float textRadio, int marginH) {

super(context,resourceId);

this.resourceId= resourceId;

drawable= context.getResources().getDrawable(resourceId);

this.textRadio= textRadio;

this.textColor= textColor;

this.marginH= marginH;

}

@Override

public int getSize(Paint paint,CharSequence text, intstart, intend,Paint.FontMetricsInt fm) { //设置图片块的宽度

CharSequence targetText=text.subSequence(start,end);

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int txtW = (int) Math.ceil(paint.measureText(targetText.toString()));

int fontHeight = fmPaint.descent- fmPaint.ascent;

rect=newRect(0,0,txtW,fontHeight);

return rect.right+2*marginH;

}

/**

* see detail message in android.text.TextLine

*

*@paramcanvasthe canvas, can be null if not rendering

*@paramtextthe text to be draw

*@paramstartthe text start position

*@paramendthe text end position

*@paramxthe edge of the replacement closest to the leading margin

*@paramtopthe top of the line //文本所在改行的顶部

*@paramythe baseline //文本的基准线

*@parambottomthe bottom of the line //文本所在改行的底部 及下行的顶部,xml文件中的设置的行间距

会直接影响 bottom到baseline的距离

*@parampaintthe work paint

*/

@Override

public void draw(Canvas canvas,CharSequence text, int start, int end, float x, int top, int y, int bottom,Paint paint) {

CharSequence targetText=text.subSequence(start,end);

intoldTextColor =paint.getColor();

floatoldTextSize =paint.getTextSize();

// canvas.drawLine(0,top,400,top,paint);

// canvas.drawLine(0,y,400,y,paint);

// canvas.drawLine(0,bottom,400,bottom,paint);

Paint.FontMetricsInt fmPaint = paint.getFontMetricsInt();

int oldfontascent = fmPaint.ascent;

paint.setColor(textColor);

paint.setTextSize(oldTextSize*textRadio);

fmPaint = paint.getFontMetricsInt();

int txtW = (int) Math.ceil(paint.measureText(targetText.toString()));

int fontHeight = fmPaint.descent- fmPaint.ascent;

canvas.save();

canvas.translate(marginH+x,y+oldfontascent);//移动到该块的原点

drawable.setBounds(rect);//背景的绘制

drawable.draw(canvas);

Log.e("尺寸",rect.bottom-((rect.bottom-fontHeight))+","+(0-oldfontascent*textRadio));

canvas.translate((rect.right-txtW)/2.0f,rect.bottom/2.f+fontHeight/2-fmPaint.descent); //移动的值是相对的。移动到“块”中字体“服务中”baseline

canvas.drawText(targetText.toString(),0,0,paint);

paint.setColor(oldTextColor);

paint.setTextSize(oldTextSize);

canvas.restore();

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/498358.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java 动态添加定时器_quartz实现任务动态增加和删除

场景这几天做项目的时候遇到了个状态自动切换的场景。该场景具体情况如下:用户可以创建多个活动活动有开始时间和结束时间活动有个状态:未上线、未开始(上线但未到开始时间)、进行中(上线且处于开始时间和结束时间之间)、已结束(上线且处于活动结束时间之…

未来IT的三驾马车:AI、物联网和混合云

来源:物联网智库 概要:未来的信息技术系统日益专注于数据在哪里生成和处理、数据如何提供和收集,以及这些数据移动起来有多快。找到一条最高效的路径是关键。 物联网、AI和混合云是同一个三角形的三条边,是同一条凳子的三条腿&…

梅宏院士:软件定义的未来——万物皆可互联,一切均可编程 | CNCC 2017

作者:杨文 摘要:结合当下的人工智能热潮,梅宏教授认为我们正在进入一个软件定义的时代。软件定义的技术本质是把原先一体化的硬件设施打破,将基础硬件虚拟化并提供标准化的基本功能,然后通过管控软件,控制其…

php字符串转int,php怎样将字符串转为int类型

php将字符串转为int类型的方法:可以利用内置函数intval()来实现。intval()函数用于获取变量的整数值,如果执行成功则返回integer值,如果执行失败则返回0,例如:【intval(“1”)】。函数介绍:intval() 函数用…

对抗攻击最新研究:仅修改「一个像素」即可骗过神经网络!

编译:BaymaxZ 作者:Jiawei Su、Danilo Vasconcellos Vargas、Sakurai Kouichi(九州大学) 摘要:在图像识别领域,基于DNN的方法克服了传统的图像处理技术,甚至达到媲美人类的结果。 最近的研究证实…

php 去掉不可见字符串,php删除不可见的Unicode字符

在论坛/社区中一般帖子/文章的标题肯定是要求不为空的,但是今天发现了一个神奇的事情,我在后台php代码中限制了title不能为空。if(preg_match(/^\s*$/, $val)) return false;但是神奇的发现在数据库中有几篇文章文章的title是空的(眼睛看起来)而且鼠标点…

李飞飞新研究:基于深度学习和视觉化语言来了解不同物体间的关系

来源:凤凰科技 概要:最近她所在的实验室正在做一项新研究,基于深度学习和视觉化语言模式了解不同物体之间的关系。 2017未来科学大奖颁奖典礼暨未来论坛年会28、29日在京举办,斯坦福大学终身教授、谷歌云首席科学家李飞飞在人工智…

php设置文件权限问题,php以fastCGI的方式运行时文件系统权限问题及解决方法

今天准备将一个php demo放在IIS下运行,网站在IIS下的配置是这样的:应用程序池是集成模式下的.net framework 2.0(2.0或4.0没什么关系,因为php以fastCGI的方式在跑), 应用程序池标识配置为IIS内置的NETWORKSERVICE, 使用的认证方式为匿名身份验…

马化腾公开信:AI将成为基础设施,腾讯要打造“数字生态共同体”

来源:亿欧 概要:马化腾认为,云计算、大数据、人工智能等技术逐渐成为新型基础设施。在数字化背景下,不同产业和区域的生态之间,开始发生越来越多的关联。 马化腾认为,云计算、大数据、人工智能等技术逐渐成…

来认识世界上第一支AI基金:模仿股票分析师 365天无间断工作

来源:机械鸡 概要:本周,EquBot公司和ETF经理集团(ETFManagers Group或ETFMG)合作推出了世界第一支人工智能ETF(ETF:交易型开放式指数基金)。 本周,EquBot公司和ETF经理集…

中国研制出首款搭载寒武纪AI芯片的人工智能服务器

来源: 澎湃、新华网 摘要:在线推理业务不同于离线训练,推理不需要密集的计算能力,而是需要及时响应。 10月30日从我国高性能计算领军企业中科曙光获悉,中科曙光近日成功研…

开发java流程步骤,优秀Java开发人员的10个步骤

一、对OO原则有很强的基础和理解对于Java开发人员来说,必须对面向对象编程有很强的理解。没有在OOPS上有很强的基础,就不能实现像Java这样的面向对象编程语言的美。如果你不知道什么是OOPS,即使使用的是OOP语言,可能仍然在以过程的…

干货!解读2016-2017全球人工智能技术及产业发展的现状及趋势~

来源: 龙为科技 摘要:报告围绕人工智能的技术原理和突破进行了重点阐述,深入分析了国外科技巨头企业在人工智能领域的布局和进展情况,概括总结了各国政府推动人工智能发展的政策措施。 国家工业信息安全发展研究中心(工…

自动化对就业没有影响?看看这张图再说

来源:36Kr 摘要:自动化就在所有人的眼皮底下进行着,大家现在才开始真正讨论其自动化未来可能会减少很大一部分人口的收入的潜在危险。 机器人远在天边近在眼前。我们不要再视而不见了。 我们正在面临第四次工业革命。很多人都在讨论其对未来的…

Gartner公布2018十大技术发展趋势 2025年AI重塑商业模式

来源: 智东西 摘要:智能数字格网将作为未来数字业务和生态系统的基础,IT领导者们在制定创新性决策时必须将其考虑在内,否则将面临巨大风险。 近日,全球领先的信息技术研究和顾问公司Gartner公布了将在2018年对大部分企…

全球研发开支排名:亚马逊第一,BATJ排不上号!

来源: 全球人工智能 摘要:虽然亚马逊可能是研发领导者,但是截至目前缺乏关于它的准确数字。 这图是全球全球研发开支排名和相关数据: 全球研发开支领导者 对于旨在内部进行创新的那些公司来说,资金需要投入到公司收益…

matlab 怎么话3维图,用matlab画三维图形

将plot3d放在matlab根目录下,然后在窗口处输入椭球的一般方程就行了。注意要把等式右边的移过来,让右边为0.椭球和平面源代码:function plot3d(varargin)if ishandle(varargin{1})cax varargin{1};axes(cax);args{:} varargin{2:end};elsear…

任正非最新讲话透露:华为在加快开发统一的人工智能平台

来源:华为心声社区 概要:华为在人工智能方面,最有条件,也最容易找到感觉的,无疑是在GTS(全球技术服务)领域。 华为在人工智能方面,最有条件,也最容易找到感觉的&#xf…

Google智能生态链的演进路径

来源: 本翼资本CapitalWings 概要:谷歌作为全球最大的信息服务公司,自搜索引擎起家,现今已成为业务涵盖人工智能、智能家居、高速网络、医疗服务、生命科学、无人驾驶等前沿科技的Alphabet公司。 谷歌作为全球最大的信息服务公司&…

博世投资张翠波:自动驾驶需要突破芯片、传感器、深度学习算法等关键技术

来源:36氪 概要:基于博世的很多发现,整个无人驾驶的时间表可能如下:Level3级别的自动驾驶可能会在2020年后;Level4量产的时间是2020到2023年。 全球智能驾驶行业风起云涌,大量资本、技术、人才不断涌入。在…