/**
* @param text 要绘制的文本
* @param x 正在绘制的文本的原点的x坐标
* @param y 正在绘制的文本的基线()的y坐标
* @param paint 文字的画笔
*/
public void drawText( String text, float x, float y, Paint paint)
从上方的drawText函数我们知道要想绘制一个居中显示的文本,除了要传入绘制的文字和绘制文字的画笔外,最重要的是参数 x 和 y 。
为了直观了解 参数 x 和 y ,参考下图:
在上图中我们可以很清楚地知道
- 参数x的取值为:包裹文本的绿框的左边在 显示矩形(中间的黑框)的x轴坐标值;
- 参数y的取值为:baseline在显示矩形(中间的黑框)的y轴坐标;
代码展示:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.xx.xxx.CView
android:layout_marginLeft="20dp"
android:layout_marginTop="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RelativeLayout>
public class CView extends View {
private TextPaint mTextPaint;
private Paint mPaint;
private int mRectWidth;
private int mRectHeight;
private int mWidthPixels;
private Paint.FontMetricsInt mFontMetrics;
/**
* baseline在背景显示框的y坐标位置
*/
private float mBaseLineInRect;
public CView(Context context) {
this(context, null);
}
public CView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public CView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
void init() {
mTextPaint = new TextPaint();
mTextPaint.setTextSize(44);
mTextPaint.setAntiAlias(true);
mTextPaint.setColor(Color.BLUE);
mPaint = new TextPaint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
/**
* FontMetricsInt得到的相关值,是以baseline为基准计算出来的,负值表示在baseline之上,正值表示在baseline之下
* mFontMetrics.top代表baseline到textBoundRect顶部的值
* mFontMetrics.bottom代表baseline到textBoundRect底部的值
*/
mFontMetrics = mTextPaint.getFontMetricsInt();
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
mWidthPixels = displayMetrics.widthPixels;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.EXACTLY) {
mRectWidth=widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
mRectWidth = mWidthPixels / 2;
} else {
}
if (heightMode == MeasureSpec.EXACTLY) {
mRectHeight = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
mRectHeight=80;
} else {
}
setMeasuredDimension(mRectWidth,mRectHeight);
mBaseLineInRect = (mRectHeight-(mFontMetrics.bottom-mFontMetrics.top))/2+Math.abs(mFontMetrics.top);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//1.画显示背景的矩形框
Rect backgroundRect = new Rect(0, 0, mRectWidth, mRectHeight);
canvas.drawRect(backgroundRect, mPaint);
//不同文字有不同的范围框,通过Rect.centerX()拿到文本矩形框的中间位置
String text = "are you ok ?";
Rect textBoundRect = new Rect();
mTextPaint.getTextBounds(text,0,text.length(),textBoundRect);
//2.画居中字体
canvas.drawText(text,backgroundRect.centerX()-textBoundRect.centerX(),mBaseLineInRect,mTextPaint);
}
}