您当前的位置: 首页 >  ui

命运之手

暂无认证

  • 3浏览

    0关注

    747博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

【高级UI】【012】FontMetric详解,Android文字居中绘制

命运之手 发布时间:2021-06-13 15:27:49 ,浏览量:3

文字绘制和图片绘制的区别

我们绘制一张图片,一条直线,或一个矩形时

基本上确定上下左右的坐标,就确定了图片或几何元素的位置

但字体元素,由于其特殊的格式,并非从左往右,从上到下直接绘制的

字体格式的专业规范

在这里插入图片描述 Android中的FontMetric

Android中的FontMetric即是对以上字体规范的一种实现

在Android中,文字的绘制是从baseline位置开始的,它的y值为0

我们来看看FontMetric中各个字段代表的含义

  • baseline,基线,文字绘制的起始位置
  • ascent,上倾,基线到文字最高处的距离,为负数
  • descent,下倾斜,基线到文字最低处的距离
  • leading,行距,与上行文字的间隔
  • top,文字最高处坐标,等于ascent
  • bottom,文字最低处坐标,等于descent
  • height,文字总高度,ascent、descent、等于leading绝对值的总和

Android居中绘制文字

由于文字是从baseline开始绘制的,而一般我们是不知道baseline的值的,就需要自己去计算


	height = baseline + descent - ascent + leading;  //行高,文字包括行距的高度
	
	middle = baseline + ascent/2;  //以ascent的中心作为文字中心,比较美观

当我们知道了文字顶部坐标,底部坐标,或中间坐标时

根据以上两个公式,就可以推算出baseline的值,很简单

工具类封装

以下是常用方法的封装,但这个工具类有点旧了,并非严格准确

正确的方法是按以上两个公式推算,偷懒的就用下面的工具类吧


	import android.graphics.Canvas;
	import android.graphics.LinearGradient;
	import android.graphics.Paint;
	import android.graphics.Rect;
	import android.graphics.Shader;
	import android.text.TextPaint;
	import android.view.Gravity;
	import android.widget.TextView;
	
	import androidx.annotation.ColorRes;
	
	import com.easing.commons.android.helper.exception.BizException;
	import com.easing.commons.android.value.color.Colors;
	
	@SuppressWarnings("all")
	public class CanvasPainter {
	
	    //获取文字宽度
	    public static float getTextWidth(Paint paint, String text) {
	        float width = paint.measureText(text);
	        return width;
	    }
	
	    //获取文字高度
	    public static float getTextHeight(Paint paint) {
	        float height = (paint.getTextSize() + 0.00000007F) / 0.7535F;
	        return height;
	    }
	
	    //获取文字水平中心位置
	    public static float getTextCenterX(TextView textView, String text) {
	        TextPaint paint = textView.getPaint();
	        float textWidth = getTextWidth(paint, text);
	        int gravity = textView.getGravity();
	        if ((gravity & Gravity.LEFT) == Gravity.LEFT)
	            return textView.getPaddingLeft() + textWidth / 2;
	        if ((gravity & Gravity.RIGHT) == Gravity.RIGHT)
	            return textView.getMeasuredWidth() - textView.getPaddingRight() - textWidth / 2;
	        if ((gravity & Gravity.CENTER_HORIZONTAL) == Gravity.CENTER_HORIZONTAL)
	            return textView.getPaddingLeft() + (textView.getMeasuredWidth() - textView.getPaddingLeft() - textView.getPaddingRight()) / 2;
	        throw BizException.of("unknown horizontal alignment");
	    }
	
	    //获取文字竖直中心位置
	    public static float getTextCenterY(TextView textView) {
	        TextPaint paint = textView.getPaint();
	        float textHeight = getTextHeight(paint);
	        int gravity = textView.getGravity();
	        if ((gravity & Gravity.TOP) == Gravity.TOP)
	            return textView.getPaddingTop() + textHeight / 2;
	        if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM)
	            return textView.getMeasuredHeight() - textView.getPaddingBottom() - textHeight / 2;
	        if ((gravity & Gravity.CENTER_VERTICAL) == Gravity.CENTER_VERTICAL)
	            return textView.getPaddingTop() + (textView.getMeasuredHeight() - textView.getPaddingTop() - textView.getPaddingBottom()) / 2;
	        throw BizException.of("unknown vertical alignment");
	    }
	
	    //从中间开始绘制文字
	    public static void drawTextFromCenter(Canvas canvas, Paint paint, String text, Number centerX, Number centerY) {
	        float textWidth = getTextWidth(paint, text);
	        Paint.FontMetrics metrics = paint.getFontMetrics();
	        canvas.drawText(text, 0, text.length(), centerX.floatValue() - textWidth / 2, centerY.floatValue() - (metrics.ascent + metrics.descent) / 2, paint);
	    }
	
	    //从左下角开始绘制文字
	    public static void drawTextFromLeftBottom(Canvas canvas, Paint paint, String text, Number left, Number bottom) {
	        float textHeight = getTextHeight(paint);
	        Paint.FontMetrics metrics = paint.getFontMetrics();
	        canvas.drawText(text, 0, text.length(), left.floatValue(), bottom.floatValue() - textHeight / 2 - (metrics.ascent + metrics.descent) / 2, paint);
	    }
	
	    //从左上角开始绘制文字
	    public static void drawTextFromLeftTop(Canvas canvas, Paint paint, String text, Number left, Number top) {
	        float textHeight = getTextHeight(paint);
	        Paint.FontMetrics metrics = paint.getFontMetrics();
	        canvas.drawText(text, 0, text.length(), left.floatValue(), top.floatValue() + textHeight / 2 - (metrics.ascent + metrics.descent) / 2, paint);
	    }
	
	    //从顶部中间开始绘制文字
	    public static void drawTextFromTopCenter(Canvas canvas, Paint paint, String text, Number centerX, Number top) {
	        float textWidth = getTextWidth(paint, text);
	        float textHeight = getTextHeight(paint);
	        Paint.FontMetrics metrics = paint.getFontMetrics();
	        canvas.drawText(text, 0, text.length(), centerX.floatValue() - textWidth / 2, top.floatValue() + textHeight / 2 - (metrics.ascent + metrics.descent) / 2, paint);
	    }
	
	    //从底部中间开始绘制文字
	    public static void drawTextFromBottomCenter(Canvas canvas, Paint paint, String text, Number centerX, Number bottom) {
	        float textWidth = getTextWidth(paint, text);
	        float textHeight = getTextHeight(paint);
	        Paint.FontMetrics metrics = paint.getFontMetrics();
	        canvas.drawText(text, 0, text.length(), centerX.floatValue() - textWidth / 2, bottom.floatValue() - textHeight / 2 - (metrics.ascent + metrics.descent) / 2, paint);
	    }
	
	    //画矩形色块
	    public static void drawColorRect(Canvas canvas, Number left, Number top, Number right, Number bottom, @ColorRes int colorId) {
	        canvas.save();
	        canvas.clipRect(new Rect(left.intValue(), top.intValue(), right.intValue(), bottom.intValue()));
	        canvas.drawColor(Colors.getColor(colorId));
	        canvas.restore();
	    }
	
	    //画直线
	    public static void drawLine(Canvas canvas, Paint paint, Number left, Number top, Number right, Number bottom) {
	        canvas.drawLine(left.intValue(), top.intValue(), right.intValue(), bottom.intValue(), paint);
	    }
	
	    //画矩形
	    public static void drawRect(Canvas canvas, Paint paint, Number left, Number top, Number right, Number bottom) {
	        canvas.drawRect(left.intValue(), top.intValue(), right.intValue(), bottom.intValue(), paint);
	    }
	}

关注
打赏
1654938663
查看更多评论
立即登录/注册

微信扫码登录

0.1742s