一、概述
1.基线
canvas在利用drawText绘制文字时,是有规则的,这个规则就是基线,当基线确定时,文字的位置也就确定了
如图上面红色的线就是基线
2.canvase的drawText()
1.canvas.drawText()与基线
public class CircleView extends View {
public CircleView(Context context){
super(context);
}
public CircleView(Context context, AttributeSet attr) {
super(context,attr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int baseLineX = 0;
int baseLineY = 200;
String text = "Hello World";
Paint paint = new Paint();
paint.setStrokeWidth(7);
paint.setColor(Color.RED);
paint.setTextSize(200);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawLine(baseLineX,baseLineY,3000,baseLineY,paint);
paint.setColor(Color.GREEN);
canvas.drawText(text,baseLineX,baseLineY,paint);//以(0,200)为原点
}
}
MainActivity中
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:id="@+id/root"
android:layout_height="fill_parent">
<com.example.myview.CircleView
android:id="@+id/circleView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
蓝色的点为原点坐标,即传入(x,y)的值。我的理解x的值可想为矩形距左边的位置,y值可想为矩形距离顶部的位置
- 当x坐标,基线位置,文字大小确定以后,文字的位置也就确定了
2.paint.setTextAlign(Paint.Align.XXX)
- 原点坐标中的x代表所要绘制文字所在矩形的相对位置。相对位置就是指指定点(x,y)在在所要绘制矩形的位置。我们知道所绘制矩形的纵坐标是由Y值来确定的,而相对x坐标的位置,只有左、中、右三个位置了。也就是所绘制矩形可能是在x坐标的左侧绘制,也有可能在x坐标的中间,也有可能在x坐标的右侧
paint.setTextAlign(Paint.Align.LEFT)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int baseLineX = 0;
int baseLineY = 200;
String text = "Hello World";
Paint paint = new Paint();
paint.setTextSize(200);
paint.setStrokeWidth(7);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawLine(baseLineX,baseLineY,3000,baseLineY,paint);
paint.setColor(Color.GREEN);
paint.setTextAlign(Paint.Align.LEFT);//原点(x,y)在矩形的左侧,矩形从(x,y)的点开始绘制
canvas.drawText(text,baseLineX,baseLineY,paint);
}
paint.setTextAlign(Paint.Align.CENTER);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int baseLineX = 0;
int baseLineY = 200;
String text = "Hello World";
Paint paint = new Paint();
paint.setTextSize(200);
paint.setStrokeWidth(7);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawLine(baseLineX,baseLineY,3000,baseLineY,paint);
paint.setColor(Color.GREEN);
paint.setTextAlign(Paint.Align.CENTER);//原点(x,y)在矩形的中间,系统会根据(x,y)的位置和文字所在矩形大小,会计算出当前开始绘制的点,使得原点(x,y)正好在所要绘制的矩形的正中间。
canvas.drawText(text,baseLineX,baseLineY,paint);
}
paint.setTextAlign(Paint.Align.RIGHT);
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int baseLineX = 0;
int baseLineY = 200;
String text = "Hello World";
Paint paint = new Paint();
paint.setTextSize(200);
paint.setStrokeWidth(7);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawLine(baseLineX,baseLineY,3000,baseLineY,paint);
paint.setColor(Color.GREEN);
paint.setTextAlign(Paint.Align.RIGHT);//原点(x,y)在矩形的右侧,相当于矩形的结束位置为(x,y)
canvas.drawText(text,baseLineX,baseLineY,paint);
}
3.FontMetrics
除了基线以外,如图所示(上图中bottom和descent并不是同一条线,图中两条线挨的比较近),另外还有四条线,分别是ascent,descent,top,bottom,他们的意义分别是:
- ascent: 系统建议的,绘制单个字符时,字符应当的最高高度所在线
- descent:系统建议的,绘制单个字符时,字符应当的最低高度所在线
- top: 可绘制的最高高度所在线
- bottom: 可绘制的最低高度所在线
(1)利用FontMetrics中的方法得到四条线
Paint.FontMetrics fontMetrics = paint.getFontMetrics();//获取FontMetrics对象
float ascent = fontMetrics.ascent + baseLineY;
float top = fontMetrics.top + baseLineY;
float descent = fontMetrics.descent + baseLineY;
float bottom = fontMetrics.bottom + baseLineY;
FontMetrics中的ascent,descent,top,bottom这个变量的值用来计算这四条条线的位置,并不等价于画出来的四条线,可以自己先画出四条FontMetrics中的ascent,descent,top,bottom这个变量的值,再画出所要的ascent,descent,top,bottom,可看出差别
(2)获取FontMetrics对象
Paint paint = new Paint();
Paint.FontMetrics fm = paint.getFontMetrics();
Paint.FontMetricsInt fmInt = paint.getFontMetricsInt();
通过paint.getFontMetrics()得到对应的FontMetrics对象。这里还有另外一个FontMetrics同样的类叫做FontMetricsInt,它的意义与FontMetrics完全相同,只是得到的值的类型不一样而已,FontMetricsInt中的四个成员变量的值都是Int类型,而FontMetrics得到的四个成员变量的值则都是float类型的。
(3)代码实现
public class CircleView extends View {
public CircleView(Context context){
super(context);
}
public CircleView(Context context, AttributeSet attr) {
super(context,attr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int baseLineX = 0;
int baseLineY = 200;
String text = "Hello World";
Paint paint = new Paint();
paint.setTextSize(120);
paint.setStrokeWidth(3);
paint.setTextAlign(Paint.Align.LEFT);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
float ascent = fontMetrics.ascent + baseLineY;
float top = fontMetrics.top + baseLineY ;
float descent = fontMetrics.descent + baseLineY;
float bottom = fontMetrics.bottom + baseLineY;
paint.setColor(Color.GREEN);
canvas.drawLine(baseLineX,baseLineY,3000,baseLineY,paint);
paint.setColor(Color.RED);
canvas.drawLine(baseLineX,ascent,3000,ascent,paint);
paint.setColor(Color.BLUE);
canvas.drawLine(baseLineX,top,3000,top,paint);
paint.setColor(Color.RED);
canvas.drawLine(baseLineX,descent,3000,descent,paint);
paint.setColor(Color.BLUE);
canvas.drawLine(baseLineX,bottom,3000,bottom,paint);
paint.setColor(Color.GREEN);
canvas.drawText(text,baseLineX,baseLineY,paint);
}
}
二、所绘文字宽度、高度和最小矩形获取
1.获取文字宽度和高度
float height = bottom - top;//高度
float width = paint.measureText(text);//宽度
2绘制最小矩形与最大矩形
paint.getTextBounds()得到最小矩形
Rect minRect = new Rect();
paint.getTextBounds(text,0,text.length(),minRect);
Log.i("Test",minRect.toShortString());
打印粗来的左上角的Y坐标是个负数,因为我们没有给getTextBounds()传递基线位置。那它就是以(0,0)为基线来得到这个最小矩形的!所以这个最小矩形的位置就是以(0,0)为基线的结果。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int baseLineX = 0;
int baseLineY = 200;
String text = "Hello World";
Paint paint = new Paint();
paint.setTextSize(120);
paint.setStrokeWidth(3);
paint.setTextAlign(Paint.Align.LEFT);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
int top = (int) (fontMetrics.top + baseLineY);
int bottom = (int) (fontMetrics.bottom + baseLineY);
int width = (int) paint.measureText(text);
paint.setColor(Color.GREEN);
Rect rect = new Rect(baseLineX,top,width,bottom);
canvas.drawRect(rect,paint);
paint.setColor(Color.RED);
Rect minRect = new Rect();
paint.getTextBounds(text,0,text.length(),minRect);
minRect.top = minRect.top + baseLineY;
minRect.bottom = minRect.bottom + baseLineY;
canvas.drawRect(minRect,paint);
paint.setColor(Color.BLACK);
canvas.drawText(text,baseLineX,baseLineY,paint);
}