一、绘制文本

在Canvas中绘制文本,使用前面文章的坐标系

1、drawText的几种方法

public void drawText (String text, float x, float y, Paint paint)

public void drawText (String text, int start, int end, float x, float y, Paint paint)

public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)

public void drawText (char[] text, int index, int count, float x, float y, Paint paint)

public void drawText (String text, float x, float y, Paint paint)

x 、 y轴表示绘制文本左下角到坐标

mPaint.setColor(Color.RED);

mPaint.setTextSize(50);

String string="HeDan";

canvas.drawText(string,0,0,mPaint);

xyText.png

public void drawText (String text, int start, int end, float x, float y, Paint paint)

绘制一部分Text,start表示从第几个字符开始,end表示第几个字符之前结束

//public void drawText (String text, int start, int end, float x, float y, Paint paint)

canvas.drawText(string,0,3,0,0,mPaint);

starttext.png

public void drawText (CharSequence text, int start, int end, float x, float y, Paint paint)使用CharSequence绘制,方法,效果同上

public void drawText (char[] text, int index, int count, float x, float y, Paint paint)使用字符数组绘制,方法,效果同上

2、drawPosText

给文本中到每个字符都设定一个坐标,不推荐使用

3、drawTextOnPath

通过Path进行文本绘制,path是一个比较重要且有趣的东西,在之后涉及知识中会进行分析。

Path path = new Path();

path.lineTo(0,200);

canvas.drawTextOnPath(string,path,100,100,mPaint);

这里简单写一个,path为一条从原点到(0,200)的直线,水平偏移量、垂直偏移量都设置为100,效果如下:

pathtext.png

二、文本居中

1、单行文本居中

a、 public void getTextBounds(String text, int start, int end, Rect bounds)

通过Rect获取文本宽度和高度,方法如下

Rect rect = new Rect();

mPaint.getTextBounds(string,0,string.length(),rect);

int width = rect.width();//文本宽度

int height = rect.height();//文本高度

b、getFontMetrics(),getFontMetricsInt()用于返回字符串的测量,而两个方法的区别就是返回值得类型。返回值一共五个属性:

Top: baseline到文本顶部的最大的距离

Ascent:baseline到文本顶部到推荐距离

Descent:baseline到文本底部到推荐距离

Bottom:baseline到文本底部到最大距离

Leading:两行文本之间推荐到额外距离,一般为0(推荐不考虑)

String-Center.png

在Android的坐标系中,向下为Y轴正方向,向上为Y轴负方向,所部baseling之上到Top与Ascent都是负数,而baselin之下到Descent、Bottom都是正数。如果要让字符串在垂直方向上居中,则需要在纵坐标上增加Asecent绝对值与descent的差。

Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;

canvas.drawText(string,0,textHeight,mPaint);

ycentent.png

c、setTextAlign可以设置画笔绘制文本到对齐方式,选择center即可完成文本到水平居中

Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;

mPaint.setTextAlign(Paint.Align.CENTER);

canvas.drawText(string,0,textHeight,mPaint);

xcentent.png

d、measureText可以测量文本的宽度,即横向长度,这样也可以来完成居中设置,但在这之前,需要恢复文本对齐方式至默认设置(居左)。

Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;

float textWidth = mPaint.measureText(string);

canvas.drawText(string,-textWidth/2,textHeight,mPaint);

效果同上C。

2、多行文本居中

有设定好的字符串数组,画笔,画布,坐标点

1、drawText每次只能绘制一行,通过for循环

2、字符串数组大于1时,每个字符到高度应该为-top+bottom,总高度为length*(-top+bottom)

3、偏移量就等于length*(-top+bottom)/2-bottom

4、如果顺序向上(Y负方向)排列到话,那么第i个字符串到高度就是-(length-i-1)*(-top+bottom)

5、每个字符串高度减去偏移量,就应该是每个字符串到baseline的y坐标

详细代码

private void textCenter(String [] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){

paint.setTextAlign(aligin);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top=fontMetrics.top;

float bottom=fontMetrics.bottom;

int length=strings.length;

float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);

float offset=total/2-bottom;

for(int i=0;i

float yAxis=-(length-i-1)*(-top+bottom)+offset;

canvas.drawText(strings[i]+"",point.x,point.y+yAxis,paint);

}

}

偏移量取值的变化,是因为在字符串的首尾两个字符串,需要把top改成ascent,bottom改成descent。通过设置画笔来完成横向的居中,居左,居右。

使用代码

String[] striings={"HeDan","是","一","个","好","学","生"};

//String[] striings={"床前明月光,","疑是地上霜。","举头望明月,","低头思故乡。"};

Point point=new Point(0,0);

//textCenter(striings,mPaint,canvas,point, Paint.Align.CENTER);

textCenter(striings,mPaint,canvas,point, Paint.Align.LEFT);

ytext.png

ytext1.png

ytext2.png

3、多列文本

1、一个字符串数组

2、每个字符数组中获取最宽到字符宽度我字符数组的宽度

3、计算数组x坐标,再掉用之前多行文本居中到代码

居右详细代码

private void textCenter(char[] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){

paint.setTextAlign(aligin);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top=fontMetrics.top;

float bottom=fontMetrics.bottom;

int length=strings.length;

float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);

float offset=total/2-bottom;

for(int i=0;i

float yAxis=-(length-i-1)*(-top+bottom)+offset;

canvas.drawText(strings[i]+"",point.x,point.y+yAxis,paint);

}

}

private void rowTextRight(String[] strings,Paint paint,Canvas canvas,Point point){

int length = strings.length;

float len ,newLen;

float total=0;

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

point.x=point.x-(int)total;

textCenter(chars,paint,canvas,point, Paint.Align.RIGHT);

point.x = point.x + (int) total;

total = total+len;

}

}

使用代码

String[] striings={"鹅,鹅,鹅,","曲项向天歌,","白毛浮绿水,","红掌拨清波,"};

Point point=new Point(0,0);

rowTextRight(striings,mPaint,canvas,point);

ytext3.png

居左详细代码

private void rowTextLeft(String[] strings,Paint paint,Canvas canvas,Point point){

int length = strings.length;

float len ,newLen;

float total=0;

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

point.x=point.x+(int)total;

textCenter(chars,paint,canvas,point, Paint.Align.LEFT);

point.x = point.x - (int) total;

total = total+len;

}

}

ytext.png

居中详细代码

private void rowTextCenter(String[] strings,Paint paint,Canvas canvas,Point point){

int length = strings.length;

float len ,newLen;

float total=0;

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

total = total+len;

}

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

if(j==0){

point.x=(int)-(total-len)/2;

}

textCenter(chars,paint,canvas,point, Paint.Align.CENTER);

point.x=point.x+(int)len;

}

}

```

ytext.png

4、文本自动换行居中

自动换行在Android 自定义View 一(初体验onDraw(),自定义属性,onMeasue()方法,测量换行)这里在介绍一个系统到方法:

StaticLayout,可以设置宽度,当前行文本超过此宽度后,进行自动换行,提供提供ALIGN_CENTER(居中)、ALIGN_NORMAL(标准)、ALIGN_OPPOSITE(与标准相反)三种对齐方式

详细代码:

private void textCenter(String string, TextPaint textPaint, Canvas canvas, Point point, int width, Layout.Alignment align,float spacingmult,float spacingadd,boolean includepad){

StaticLayout staticLayout = new StaticLayout(string,textPaint,width, align,spacingmult,spacingadd,includepad);

canvas.save();

canvas.translate(-staticLayout.getWidth()/2+point.x,-staticLayout.getHeight()/2+point.y);

staticLayout.draw(canvas);

canvas.restore();

}

使用方法

String mString="HeDan是一个好学生";

TextPaint tp = new TextPaint();

tp.setColor(Color.BLUE);

tp.setStyle(Paint.Style.FILL);

Point point=new Point(0,0);

tp.setTextSize(50);

textCenter(mString,tp,canvas,point,200,Layout.Alignment.ALIGN_CENTER,1.5f,0,false);

ytext.png

下面贴出学习源码:

public class MultipleText extends View {

private Paint mPaint;

private float pWidth;

private float pHeight;

private int mWidth;

private int mHeight;

public MultipleText(Context context) {

this(context, null);

}

public MultipleText(Context context, AttributeSet attrs) {

this(context, attrs, 0);

}

public MultipleText(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

initPaint();

}

/**

* 初始化画笔

*/

private void initPaint() {

mPaint = new Paint();

mPaint.setStyle(Paint.Style.FILL);//设置画笔填充

mPaint.setAntiAlias(true);//抗锯齿

mPaint.setColor(Color.parseColor("#52adff"));//设置画笔颜色

}

;

@Override

protected void onDraw(Canvas canvas) {

super.onDraw(canvas);

canvas.translate(mWidth / 2, mHeight / 2);

mPaint.setStrokeWidth(10);//设置原点宽度

canvas.drawPoint(0, 0, mPaint);//绘制原点

canvas.drawPoints(new float[]{pWidth, 0, 0, pHeight, -pWidth, 0, 0, -pHeight}, mPaint);//绘制边缘点*/

mPaint.setStrokeWidth(1);//重新设置画笔到宽度

canvas.drawLine(-pWidth, 0, pWidth, 0, mPaint);//绘制X轴

canvas.drawLine(0, -pHeight, 0, pHeight, mPaint);//绘制Y轴

mPaint.setStrokeWidth(3);//设置箭头宽度

canvas.drawLines(new float[]{pWidth, 0, pWidth * 0.95f, -pWidth * 0.05f, pWidth, 0, pWidth * 0.95f, pWidth * 0.05f}, mPaint);//X轴箭头

canvas.drawLines(new float[]{0, pHeight, -pHeight * 0.05f, pHeight * 0.95f, 0, pHeight, pHeight * 0.05f, pHeight * 0.95f}, mPaint);//Y轴箭头

mPaint.setColor(Color.RED);

mPaint.setTextSize(50);

String string="HeDan";

//public void drawText (String text, float x, float y, Paint paint)

//canvas.drawText(string,0,0,mPaint);

//public void drawText (String text, int start, int end, float x, float y, Paint paint)

// canvas.drawText(string,0,3,0,0,mPaint);

/* Path path=new Path();

path.lineTo(0,200);

canvas.drawTextOnPath(string,path,100,100,mPaint);

Rect rect = new Rect();

mPaint.getTextBounds(string,0,string.length(),rect);

int width = rect.width();//文本宽度

int height = rect.height();//文本高度*/

/* Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();

float textHeight=(-fontMetrics.ascent-fontMetrics.descent)/2;

float textWidth = mPaint.measureText(string);

canvas.drawText(string,-textWidth/2,textHeight,mPaint);*/

/* String[] striings={"鹅,鹅,鹅,","曲项向天歌,","白毛浮绿水,","红掌拨清波,"};

Point point=new Point(0,0);

textCenter(striings,mPaint,canvas,point, Paint.Align.LEFT);

rowTextCenter(striings,mPaint,canvas,point);*/

String mString="HeDan是一个好学生";

TextPaint tp = new TextPaint();

tp.setColor(Color.BLUE);

tp.setStyle(Paint.Style.FILL);

Point point=new Point(0,0);

tp.setTextSize(50);

textCenter(mString,tp,canvas,point,200,Layout.Alignment.ALIGN_CENTER,1.5f,0,false);

}

private void textCenter(String [] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){

paint.setTextAlign(aligin);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top=fontMetrics.top;

float bottom=fontMetrics.bottom;

int length=strings.length;

float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);

float offset=total/2-bottom;

for(int i=0;i

float yAxis=-(length-i-1)*(-top+bottom)+offset;

canvas.drawText(strings[i],point.x,point.y+yAxis,paint);

}

}

private void textCenter(char[] strings, Paint paint, Canvas canvas, Point point,Paint.Align aligin){

paint.setTextAlign(aligin);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top=fontMetrics.top;

float bottom=fontMetrics.bottom;

int length=strings.length;

float total=(length-1)*(-top+bottom)+(-fontMetrics.ascent+fontMetrics.descent);

float offset=total/2-bottom;

for(int i=0;i

float yAxis=-(length-i-1)*(-top+bottom)+offset;

canvas.drawText(strings[i]+"",point.x,point.y+yAxis,paint);

}

}

private void rowTextRight(String[] strings,Paint paint,Canvas canvas,Point point){

int length = strings.length;

float len ,newLen;

float total=0;

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

point.x=point.x-(int)total;

textCenter(chars,paint,canvas,point, Paint.Align.RIGHT);

point.x = point.x + (int) total;

total = total+len;

}

}

private void rowTextLeft(String[] strings,Paint paint,Canvas canvas,Point point){

int length = strings.length;

float len ,newLen;

float total=0;

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

point.x=point.x+(int)total;

textCenter(chars,paint,canvas,point, Paint.Align.LEFT);

point.x = point.x - (int) total;

total = total+len;

}

}

private void rowTextCenter(String[] strings,Paint paint,Canvas canvas,Point point){

int length = strings.length;

float len ,newLen;

float total=0;

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

total = total+len;

}

for(int j=0;j

char[] chars = strings[j].toCharArray();

len=paint.measureText(chars[0]+"");

for (int i=1; i

newLen = mPaint.measureText(chars[i]+"");

len = Math.max(newLen,len);

}

if(j==0){

point.x=(int)-(total-len)/2;

}

textCenter(chars,paint,canvas,point, Paint.Align.CENTER);

point.x=point.x+(int)len;

}

}

private void textCenter(String string, TextPaint textPaint, Canvas canvas, Point point, int width, Layout.Alignment align,float spacingmult,float spacingadd,boolean includepad){

StaticLayout staticLayout = new StaticLayout(string,textPaint,width, align,spacingmult,spacingadd,includepad);

canvas.save();

canvas.translate(-staticLayout.getWidth()/2+point.x,-staticLayout.getHeight()/2+point.y);

staticLayout.draw(canvas);

canvas.restore();

}

@Override

protected void onSizeChanged(int w, int h, int oldw, int oldh) {

super.onSizeChanged(w, h, oldw, oldh);

mWidth = w;

mHeight = h;

pWidth = mWidth / 2 * 0.8f;//X轴边缘原点到原点到距离

pHeight = mHeight / 2 * 0.8f;//Y轴边缘原点到原点到距离

}

android多行文字正中间显示,Android自定义View五(绘制文本大小、多行多列居中)...相关推荐

  1. HenCoder Android 开发进阶:自定义 View 1-5 绘制顺序

    这期是 HenCoder 自定义绘制的第 1-5 期:绘制顺序 之前的内容在这里:  HenCoder Android 开发进阶 自定义 View 1-1 绘制基础  HenCoder Android ...

  2. Android零基础入门第24节:自定义View简单使用

    Android零基础入门第24节:自定义View简单使用 原文:Android零基础入门第24节:自定义View简单使用 当我们开发中遇到Android原生的组件无法满足需求时,这时候就应该自定义Vi ...

  3. Android 角标 小圆点 右上角显示数字 自定义角度

    效果如图 首先添加依赖: // 角标implementation 'q.rorbin:badgeview:1.1.3' 设置角标 比较关键的是布局配合 <FrameLayoutandroid:i ...

  4. android通过代码设置铃声_Android基础(5)—自定义View

    自定义View 基本认知: 虽然Android已经自带来很多强大的UI控件,但是依旧不能满足所有开发人员的需求.通常开发人员需要实现设计师精心设计的视觉效果,这样情况下可能现有的控件就不能满足需求或者 ...

  5. 精通Android自定义View(五)自定义属性值使用详情

    1 可查看Android自定义View的基本使用 1 精通Android自定义View(一)自定义控的基本使用 2 精通Android自定义View(二)自定义属性使用详解 2 string 字符串 ...

  6. <android>音乐频谱显示效果 音乐播放动画 自定义view Visualizer 对接MediaPlayer 声音频率 动画效果

    最近写了一个音乐频谱显示效果的自定义view,通过Visualizer 函数对接了MediaPlayer的声源byte数据的回调,全部封装到了view的里面,外部只需要设置一个MediaPlayer即 ...

  7. android控件向内弧度_安卓自定义 View 基础:坐标系、角度弧度、颜色

    安卓自定义View基础 - 坐标系 一.屏幕坐标系和数学坐标系的区别 由于移动设备一般定义屏幕左上角为坐标原点,向右为x轴增大方向,向下为y轴增大方向, 所以在手机屏幕上的坐标系与数学中常见的坐标系是 ...

  8. 精通Android自定义View(八)绘制篇Canvas分析之绘制文本

    1 简述 绘制文字分为三种应用场景: 情况1:指定文本开始的位置 即指定文本基线位置 基线x默认在字符串左侧,基线y默认在字符串下方 情况2:指定每个文字的位置 情况3:指定路径,并根据路径绘制文字 ...

  9. python显示html内容自动换行_canvas绘制文本内容自动换行

    原型要求: 要求制作一个邀请卡页面,其中标题字数是动态的,最多可显示2行,如果超出2行则第2行内容结尾添加省略号.根据产品妹子的性格,四行这个设置到时很大机会改,所以这里一定不能写死,结果前几天真的要 ...

最新文章

  1. IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期
  2. 高精度除以低精度板子
  3. java encodedurl_Java ParseUtil.fileToEncodedURL方法代码示例
  4. python 理解Matplotlib 3D (三维图) 绘图函数 plot_surface 的 rstride 和 cstride参数
  5. 什么是java?为什么大家都学习java技术?
  6. createprocess 系统找不到指定的文件_windows找不到gpedit.msc请确定文件名
  7. 在oracle中如何复制用户的权限不够,linux 普通用户下 移动或复制一个zip文件权限不够怎么办...
  8. 先进先出算法_结构与算法(02):队列和栈结构
  9. windows 虚拟地址映射到物理地址
  10. 工厂模式个人案例_工厂设计模式案例研究
  11. java自定义栈类代码,异常堆栈和自定义类
  12. Could not find artifact org.olap4j:olap4j:pom:0.9.7.309-JS-3 in alimaven
  13. MVC4发布到IIS,出现HTTP 错误 404.0 - Not Found的解决方法
  14. 个人财务管理系统mysql_个人财务管理系统功能模块设计
  15. CGLIB 动态代理使用
  16. Spyder中出现IndentationError:unindent does not match any outer indentation level错误
  17. NTP时钟源(GPS时间源)介绍与分析
  18. 墨刀导出html无法使用,墨刀用户必读,能解决你80%的问题(持续更新中)
  19. openssl 1.0.2k-fips 升级到 openssl-3.0.3
  20. LOL代练检测——2019腾讯游戏安全技术竞赛决赛记录

热门文章

  1. 2013~2018年企业邮箱市场分析数据--市场规模、市场容量、市场份额及发展趋势...
  2. 【UE4 第一人称射击游戏】01-真实的第一人称相机
  3. STM8S003F3通过PWM波实现三基色呼吸灯
  4. docker 一些命令
  5. c语言程序设计安卓,C语言编程宝典最新版下载-C语言编程宝典appv1.7.1 安卓版-腾牛安卓网...
  6. windows下Redis 主从读写分离部署
  7. SOT23-6,两通道电容式触摸感应 IC
  8. 凌恩客户文章|《Microbiome》:宏基因组构建反刍动物全消化道超1万个MAGs新进展
  9. 那些经验丰富的数据科学家每天在干什么?
  10. JAVA多线程实现和应用总结