自定义view(五):自定义view使文字居中对齐显示
来源:互联网 发布:linux启动u盘制作工具 编辑:程序博客网 时间:2024/05/21 17:15
接着上一篇文章 自定义view(四):自定义view实现动态按钮
今天在自定义view中加上一个文字显示。
本以为,这个挺简单的,但是没想到文字加上后,发现不居中。
设置了 mPaintTv.setTextAlign(Paint.Align.CENTER);
发现只能文字左右居中,上下依然不是正中心。like this
中间的红线是中心线,但是文字却不是跟中心对齐的,而是文字底部跟中心线平齐。
这显然不符合按钮的显示啊,查阅了一下资料,发现,自定义view在drawText时候,这个文字的对齐还真的是有个小坑。
上图是从网上找到的,但是里面有一个坑,后面会讲。
**先解释下,drawText(String text,float x,float y,Paint paint)
里面的x参数,在paint未设置setTextAlign
时,默认是从横坐标x点处开始绘制第一个字符串的字符。
如果mPaintTv.setTextAlign(Paint.Align.CENTER);
则是整个字符串的中心点的横坐标是x
里面的y参数永远都跟 字符串的Baseline对齐。**
这也就是为什么我们用矩形的中心点去绘制text的时候,文字却不在正中心,反而是有些向上偏移。
like this:
所以绘制的时候我们要把文字偏移的那段距离算出来:
那么坑就出来了 :【前方高能】
通过Paint.FontMetrics fm = mPaintTv.getFontMetrics();
可以获得字体属性类FontMetrics
而 FontMetrics 里面有两个很重要的属性就是ascent 和 descent
他们表示的不仅仅是如下图的距离,如果你debug过,会发现他们还带有正负号,
说实话,当时我感觉真是日了哈士奇了。后来我发现,这也是可以理解的。
就如图所示,以baseline为x轴,向下是正方向,向上为负方向。
所以ascent永远都是负值。
搞清楚了这一点,我们就可以大大方方的计算了。
如果想要文字居中显示,肯定是以中心线(虚线)为x轴了,但是现在是以baseline为x轴,只需要计算出中心线和baseline之间的距离即可(中心线与baseline之间的距离 = 中心线到底部的距离 - descent)。
首先:
中心线到底部的距离是 = 整个文字的高度 / 2 ;即(-ascent + descent)/2
中心线与baseline之间的距离 = (-ascent + descent)/ 2 - descent ;即 (-ascent-descent) / 2
然后,只需要在drawText时候将y参数向上提高 中心线与baseline之间的距离即可
canvas.drawText("bjjg",maxWidth/2,maxHeight/2 - (fm.descent - (-fm.ascent + fm.descent)/2),mPaintTv);
全部代码如下:
/** * Created by FanHaiChao on 2017/4/12. * 自定义的带动画的view */public class MyButtonView extends View { private Paint mPaintBg; private Paint mPaintTv; private RectF rect; private float radius; private int index = 0; private int maxIndex = 24; private boolean isDraw = false;//是否绘制完成:true--绘制完成;false--未绘制完成 private boolean isTo0 = false;//true:变显示, false:变消失 public MyButtonView(Context context) { this(context,null); } public MyButtonView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public MyButtonView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private void initView() { mPaintBg = new Paint(); mPaintBg.setAntiAlias(true); mPaintBg.setStyle(Paint.Style.FILL); mPaintBg.setColor(Color.RED); mPaintTv = new Paint(); mPaintTv.setAntiAlias(true); mPaintTv.setStyle(Paint.Style.FILL); mPaintTv.setColor(Color.WHITE); mPaintTv.setTextSize(36); mPaintTv.setTextAlign(Paint.Align.CENTER); } //每一帧 onDraw一次 index变一次 ondraw一次 //注意onDraw 方法 会在view所在activity可见时调用,也就是说 view 重新可见时 也会调用onDraw @Override protected void onDraw(Canvas canvas) { if (isDraw) { float maxWidth = getWidth(); float maxHeight = getHeight(); if (index <= (maxIndex / 2)) {//前一半时间画圆,后一半时间画圆角矩形 canvas.drawCircle(maxWidth / 2, maxHeight / 2, radius, mPaintBg); radius = ((maxHeight / 2) / (maxIndex / 2)) * index; } else { if (maxWidth > maxHeight) { radius = maxHeight / 2; } else { radius = maxWidth / 2; } float wr = ((maxWidth / 2 - radius) / (maxIndex / 2)) * (index - maxIndex/2); //参数:左边距,上边距,右边距,下边距 rect = new RectF(maxWidth / 2 - radius - wr, 0, maxWidth / 2 + radius + wr, 2 * radius); canvas.drawRoundRect(rect, 90, 90, mPaintBg); canvas.drawLine(0,maxHeight/2,maxWidth,maxHeight/2,mPaintTv); Paint.FontMetrics fm = mPaintTv.getFontMetrics(); canvas.drawText("暴躁的码字猴",maxWidth/2,maxHeight/2 - (fm.descent - (-fm.ascent + fm.descent)/2),mPaintTv); } if (isTo0) { index--; } else { index++; index = index <= maxIndex ? index : maxIndex; } if (index <= maxIndex && index >= -1) { invalidate(); } else { System.out.println(index); } } } public void startShow(boolean draw) { isDraw = draw; if (index == maxIndex){ isTo0 = true; radius= 0; }else { isTo0 = false; radius= 0; } invalidate(); }}
- 自定义view(五):自定义view使文字居中对齐显示
- 自定义View绘制文字居中显示
- 自定义view文字在矩形里居中
- 自定义View中文本居中显示
- 自定义View绘制文字
- 自定义垂直文字view
- 自定义View实现弹出效果和文字居中
- 关于自定义view中的文字垂直居中的问题。
- Android 自定义View (五)
- Android 自定义View (五)
- 自定义View五
- Android自定义view字体居中
- android自定义View文本居中
- 自定义View(1):自定义文本显示
- 自定义View--文字两端能够对齐的TextView,文字右端能够对齐的TextView
- 文字逐渐变色(自定义View)
- 自定义View之文字游乐场(一)
- 自定义View之文字游乐场(二)
- html与css中局部技巧
- Spring Security 使web应用更加安全
- API 设计的最佳实践
- 接收到普通Exception,事务无法回滚解决方案
- 1043. Is It a Binary Search Tree (25)
- 自定义view(五):自定义view使文字居中对齐显示
- Docker镜像的备份和恢复
- spring容器通过动态代理获取bean
- 数据库
- docker学习笔记
- Python+Selenium中级篇之7-Python中字符串切割操作
- debug New table
- Java总结篇系列:Java多线程(一)
- 画图板