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

来源:互联网 发布:js 设置radio checked 编辑:程序博客网 时间:2024/06/14 03:11

问题一:在自定义控件绘制文字的时候怎么确定文字的宽度(不是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;