06自定义View之文字绘制
Posted 清风百草
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了06自定义View之文字绘制相关的知识,希望对你有一定的参考价值。
(1)android绘制文字
(2)文字绘制之认知baseline
(3)文字绘制之测量
(4)文字绘制之渐变绘制
(5)画布裁剪
(6)属性动画
(7)过度绘制
【06】自定义View之文字绘制
文章目录
1.自定义View
(1)extends View
(2)extends ViewGroup
2.文字绘制
(1)绘制
- extends AppCompatTextView
- onMeasure():确定控件显示大小
- onLayout():确定控件摆放位置
- onDraw():显示什么
(2)画布:canvas
决定绘制什么形状
(3)画笔:paint
用来设置绘制风格
(4)绘制文字重中之重,它是以基准线为中心的。
2.1绘制文字
/**
* Draw the text, with origin at (x,y), using the specified paint. The origin is interpreted
* based on the Align setting in the paint.
*
* @param text The text to be drawn
* //x:表示轴起点
* @param x The x-coordinate of the origin of the text being drawn
* //y:表示baseline的值
* @param y The y-coordinate of the baseline of the text being drawn
* @param paint The paint used for the text (e.g. color, size, style)
*/
public void drawText(@NonNull String text, float x, float y, @NonNull Paint paint) {
super.drawText(text, x, y, paint);
}
(1)baseline是什么
- 红色的线就是baseline,就是说大部分的文字都以这根线为基准对齐的线。
- baseline,就是无论多少个文字,都能在水平线上确保文字基于这条线对齐
- 可以超出基准线,文字往上往下都可以
2.1.1文字测量
Paint.FontMetrics
/**
* Class that describes the various metrics for a font at a given text size.
* Remember, Y values increase going down, so those values will be positive,
* and values that measure distances going up will be negative. This class
* is returned by getFontMetrics().
*/
public static class FontMetrics {
/**
top:表示从baseline基准线到文字最顶端的尺寸
* The maximum distance above the baseline for the tallest glyph in
* the font at a given text size.
*/
public float top;
/**
* The recommended distance above the baseline for singled spaced text.
*/
public float ascent;
/**
* The recommended distance below the baseline for singled spaced text.
*/
public float descent;
/**
* The maximum distance below the baseline for the lowest glyph in
* the font at a given text size.
*/
public float bottom;
/**
* The recommended additional space to add between lines of text.
*/
public float leading;
}
top:表示从baseline基准线到文字最顶端的尺寸
bottom:表示从baseline基准线到文字最底端的尺寸
ascent:表示从baseline到大部分文字最顶端的尺寸。
descent:表示从baseline到大部分文字最底端的尺寸。
top/bottom:无论什么文字,不会超出上界下界。
ascent/descent:正常文字的上界与下界。
文字的高度= top+bottom
如果基准线baseline为0,
top的值往上走,Android值为负(-)
bottom的值往下走,Android值为正(+)
计算文字实际的高度应该是什么样子呢?
- 文字最大的高度=bottom - top 。
- 文字正常的高度=descent - ascent。
3.文字颜色渐变绘制
3.1屏幕显示与Canvas的关系
(1)屏幕画布是有很多层叠加到一起的。
(2)如何判断绘制的内容处在同一层级
一层
canvas.save();
…这里边儿的内容处在同一层级
canvas.restore();
一层
canvas.save();
…这里边儿的内容处在同一层级
canvas.restore();
/**
* 1.文字画到屏幕中心
* (1)如何分层
* canvas.save();
* canvas.restore();
* 处在以上代码中的内容,可以理解为它们处在同一个层次
*
* @param canvas
*/
private void drawCenterText(final Canvas canvas){
canvas.save();
Paint paint = new Paint();
//单位是像素
paint.setTextSize(80);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setAntiAlias(true);
/**
*1.文字绘制在view的中心
* (1)textAlign只能设置水平方向的,因此该需求不能使用这种方法
* (2)需要计算文字的高度
* (3)Paint.FontMetrics是用于文字测量的
* (4)文字的正常高度:fontMetrics.descent - fontMetrics.ascent
*/
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
//确保居中
//baseline =getHeight()/2+(fontMetrics.descent - fontMetrics.ascent)/2 - fontMetrics.descent;
//划简的写法
float baseline = getHeight()/2-(fontMetrics.descent + fontMetrics.ascent)/2;
//x轴的居中
paint.setTextAlign(Paint.Align.LEFT);
float width = paint.measureText(mText);
float x = getWidth()/2 - width/2;
canvas.drawText(mText,x,baseline,paint);
canvas.restore();
}
3.2绘制渐变
(1)文字本身是没办法只绘制一半的
(2)通过从左往右一点一点的裁剪。
3.2.1Canvas画布的剪裁
(1)clipRect函数是android.graphics.Canvas类下一个用于对画布进行矩形裁剪的方法。
(2)它裁剪了我们想要的绘制区域 , 有点类似ps里面的遮罩效果
/**
* 1.文字画到屏幕中心
* (1)如何分层
* canvas.save();
* canvas.restore();
* 处在以上代码中的内容,可以理解为它们处在同一个层次
*
* @param canvas
*/
private void drawCenterText1(final Canvas canvas){
canvas.save();
Paint paint = new Paint();
//单位是像素
paint.setTextSize(80);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLACK);
paint.setAntiAlias(true);
/**
*1.文字绘制在view的中心
* (1)textAlign只能设置水平方向的,因此该需求不能使用这种方法
* (2)需要计算文字的高度
* (3)Paint.FontMetrics是用于文字测量的
* (4)文字的正常高度:fontMetrics.descent - fontMetrics.ascent
* 2.绘制渐变
* (1)裁剪
*/
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
//确保居中
//baseline =getHeight()/2+(fontMetrics.descent - fontMetrics.ascent)/2 - fontMetrics.descent;
//划简的写法
float baseline = getHeight()/2-(fontMetrics.descent + fontMetrics.ascent)/2;
//x轴的居中
paint.setTextAlign(Paint.Align.LEFT);
float width = paint.measureText(mText);
float left = getWidth()/2 - width/2;
canvas.drawText(mText,left,baseline,paint);
canvas.restore();
}
/**
* 通过裁剪绘制遮罩层
* @param canvas
*/
private void drawCenterText2(final Canvas canvas){
canvas.save();
Paint paint = new Paint();
paint.setTextSize(80);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setAntiAlias(true);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
//确保居中
//baseline =getHeight()/2+(fontMetrics.descent - fontMetrics.ascent)/2 - fontMetrics.descent;
//划简的写法
float baseline = getHeight()/2-(fontMetrics.descent + fontMetrics.ascent)/2;
//x轴的居中
paint.setTextAlign(Paint.Align.LEFT);
float width = paint.measureText(mText);
float left = getWidth()/2 - width/2;
//裁剪的右边为
float right = left + width*percent;
/**
* 裁剪:右边应该裁剪多少呢?
*
*/
Rect rect = new Rect((int)left,0,(int)right,getHeight());
canvas.clipRect(rect);
canvas.drawText(mText,left,baseline,paint);
canvas.restore();
}
private SimpleColorChangeTextView mView1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_jrtt_main);
mView1 = findViewById(R.id.tv_color_change_view);
//播放属性动画
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
onStartLeft(null);
}
},1000);
}
/**
* 属性动画
* @param view
*/
public void onStartLeft(View view){
//属性动画,通过属性动画的方式改变自定义View中percent的值,是通过反射改变percent属性的值。
ObjectAnimator.ofFloat(mView1,"percent",0,1).setDuration(2000).start();
}
3.3补充点
-
invalidate()方法调用时,会导致onDraw()方法重复调用
-
在onDraw()中创建对象会导致GC,会导致内存抖动,最终导致卡顿,甚至崩溃。
-
过度绘制
(1)同一个像素点,绘制了多次2次
真彩色:没有过度绘制
蓝色:过度绘制1次
绿色:过度绘制2次
粉色:过度绘制3次
红色:过度绘制4次或更多次
5.打赏鼓励
感谢您的细心阅读,您的鼓励是我写作的不竭动力!!!
5.1微信打赏
5.2支付宝打赏
以上是关于06自定义View之文字绘制的主要内容,如果未能解决你的问题,请参考以下文章
Flutter自定义View之——价格选择器|双向滑动|手势处理
Flutter自定义View之——价格选择器|双向滑动|手势处理