关于Paint了解text绘制时的基线位置关系/测量字符的宽度

问题一:在自定义控件绘制文字的时候怎么确定文字的宽度(不是view的宽度),或者其中几个字符的宽度?
下面有两个方法,可以测量指定几个字符的宽度。

    /**
     * @param text  测量的String
     * @return      返回测量宽度结果
     */
    public float measureText(String text) {}
    /**
     * @param text  要测量的字符串
     * @param start 起始测量索引
     * @param end 要测量字符结束索引
     * @return 返回测量宽度
     */
    public float measureText(CharSequence text, int start, int end) 

了解canvas.drawtext方法是要先指定基准线的位置,不然绘制会出现字体不显示的问题。如下图所示:
这里写图片描述

最后按照这个位置问题,下了下面的代码:

  public MyTestTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //初始化画五线谱paint
        linePaint = new Paint();
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(Color.RED);
        linePaint.setStrokeWidth(3.0f);
        //初始化写字的Paint
        textPaint = new Paint();
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(300);
        //设置文字的旋转角度,官方推荐-0.25
        //textPaint.setTextSkewX(-0.25f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 开始绘制文字
         * @param text  要被画的字体
         * @param x     x坐标,开始绘制
         * @param y     y坐标,注意是baseline的y值
         * @param paint The paint used for the text (e.g. color, size, style)
         */
        float ybase = 600.0f;
        canvas.drawText("ab思g", 100.0f, ybase, textPaint);
        //测量字体的高度
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float top = fontMetrics.top;
        float ascent = fontMetrics.ascent;
        float descent = fontMetrics.descent;
        float leading = fontMetrics.leading;//baseline参考基线
        float bottom = fontMetrics.bottom;
        //开始绘制残凹陷,
        //绘制baseline
        Path basePath = generatePath(50, 600);
        basePath.lineTo(1020, 600);
        canvas.drawPath(basePath, generatePaint(Color.RED));
        //bottom
        Path bottomPath = generatePath(50, ybase + bottom);
        bottomPath.lineTo(1020, ybase + bottom);
        canvas.drawPath(bottomPath, linePaint);
        //绘制descent
        Path descentPath = generatePath(50, ybase + descent);
        descentPath.lineTo(1020, ybase + descent);
        canvas.drawPath(descentPath, generatePaint(Color.BLUE));
        //绘制ascent
        float asentY = ybase + ascent;
        System.out.println("test 数值 asentY=" + asentY);
        Path asentPath = generatePath(50, asentY);
        asentPath.lineTo(1020, asentY);
        canvas.drawPath(asentPath, generatePaint(Color.DKGRAY));
        //绘制top
        Path topPath = generatePath(50, ybase + top);
        topPath.lineTo(1020, ybase + top);
        canvas.drawPath(topPath, generatePaint(Color.GREEN));
        //绘制middle
        float middleY = ybase-((bottom - top) / 2-bottom);
        Path middlePath = generatePath(0, middleY);
        middlePath.lineTo(1080,middleY);
        canvas.drawPath(middlePath,generatePaint(Color.RED));
    }

    private Paint generatePaint(int color) {
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.STROKE);
        paint.setColor(color);
        paint.setStrokeWidth(3.0f);
        return paint;
    }

    private Path generatePath(float moveX, float moveY) {
        Path path = new Path();
        path.moveTo(moveX, moveY);
        return path;
    }

最终的结果图如下,有些差别。
这里写图片描述

总结:1.实践出真知
2.top是负数,bottom’是正数,这说明都是相对于baseline而言,baseline是和leading相等的。
float top = fontMetrics.top;
float ascent = fontMetrics.ascent;
float descent = fontMetrics.descent;
float leading = fontMetrics.leading;//baseline参考基线
float bottom = fontMetrics.bottom;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值