(六)Paint 绘画文字

来源:互联网 发布:中邮证券软件 编辑:程序博客网 时间:2024/05/15 10:15

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文纯个人学习笔记,由于水平有限,难免有所出错,有发现的可以交流一下。

在绘画文字之前,先来看一下 Paint.FontMetrics 这个内部类

一.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 {        /**         * 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,ascent,baseline,desent, bottom 以及一条不被记录的文字中心线。
1.文字绘画都在 top 与 buttom 之间,这里面不包括 margin。
2.top 与 ascent 之间绘制字母的音标。
3.baseline 为字母的基线。
4.descent 与 buttom 之间正常不绘制东西。
5.文字中心线处于 top 与 buttom 中间。
这里写图片描述

Paint.FontMetricsInt 里面有 top,ascent,desent, bottom, leading 这几个属性。top,ascent,desent, bottom 这几个值分别表示对应线的 Y 坐标 - baseline 的 Y 坐标

二.圆形进度条 Demo

绘制文字时候很经常处理不好文字的绘制高度问题,要么偏高要么偏低,这边绘制一个圆形进度条,在圆中心绘制进度文字。

1.分析

这里写图片描述
1.该圆形进度条支持一系列自定义属性设置。
2.先绘制背后圆环。
3.绘制中间文字。
4.绘制进度。

2.创建自定义 View

在 attrs.xml 中定义自定义属性

   <declare-styleable name="CustomProgressBar">        <!-- 进度圆圈背景颜色 -->        <attr name="roundColor" format="color"></attr>        <!-- 进度颜色 -->        <attr name="roundProgressColor" format="color"></attr>        <!-- 进度条宽度 -->        <attr name="roundWidth" format="dimension"></attr>        <!-- 进度最大值  -->        <attr name="max" format="integer"></attr>        <!-- 是否显示文字  -->        <attr name="textShow" format="boolean"></attr>        <!-- 中间文字大小 -->        <attr name="textSize" format="dimension"></attr>        <!-- 中间文字颜色  -->        <attr name="textColor" format="color"></attr>    </declare-styleable>

自定义 View 继承 View,这时候会要求重写 View 的构造函数。View 的构造函数中比较重要的两个是 。一般就用到这两个,其他比较少。

//供程序内部实例化时候用的public View(Context context){...}//用于layout文件实例化,会把XML内的参数通过AttributeSet带入到View内public View(Context context, @Nullable AttributeSet attrs){...}

在这边,我们重写第二个构造函数。这个做过自定义的都懂,就不多讲。

    public CircleProgressBar(Context context, AttributeSet attrs) {        super(context, attrs);        paint = new Paint();        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomProgressBar);        roundColor = typedArray.getColor(R.styleable.CustomProgressBar_roundColor, Color.RED);        roundProgressColor = typedArray.getColor(R.styleable.CustomProgressBar_roundProgressColor, Color.GREEN);        roundWidth = typedArray.getDimension(R.styleable.CustomProgressBar_roundWidth, 10);        max = typedArray.getInt(R.styleable.CustomProgressBar_max, 100);        textSize = typedArray.getDimension(R.styleable.CustomProgressBar_textSize, 12);        textShow = typedArray.getBoolean(R.styleable.CustomProgressBar_textShow, true);        textColor = typedArray.getColor(R.styleable.CustomProgressBar_textColor, Color.GREEN);        typedArray.recycle();    }

在最后要进行 typedArray.recycle():按官方说法是说:对 TypedArray 进行回收,以便再次试用。点进去可以发现就是释放资源,
TypedArray 要是每次都创建 array ,对系统来说是一笔不小的开销,所以创建的方法一直点进去会发现是一个简单地单例 + 使用池的模式,每次使用完要释放资源。

3.绘制背后圆环

        /*         * 画背景圆环         */        //获取圆环半径        float radius = (getWidth() - roundWidth) / 2;        //设置抗锯齿        paint.setAntiAlias(true);        //设置画笔样式填充内部        paint.setStyle(Paint.Style.STROKE);        //设置颜色        paint.setColor(roundColor);        //设置圆环宽度        paint.setStrokeWidth(roundWidth);        //画进度条背后圆环        canvas.drawCircle(getWidth() / 2, getWidth() / 2, radius, paint);

运行效果:
这里写图片描述

4.绘制中间文字

这里主要麻烦是在计算 baseline 的 Y 坐标。需要用文字中心线算出 buttom 的 Y 坐标,从而算出 baseline 的 Y 坐标。

        /*         * 中间文字         */        if (textShow) {            paint.setStrokeWidth(0);            paint.setTextSize(textSize);            paint.setColor(textColor);            paint.setTypeface(Typeface.DEFAULT_BOLD);            //计算百分比            int percent = (int) ((float)progress / max * 100);            //要显示的百分比字符串            String strPercent = percent + "%";            //获取 Paint.FontMetricsInt 对象            Paint.FontMetricsInt fm = paint.getFontMetricsInt();            //计算字符串起始的 X 坐标            float strX = getWidth() / 2 - paint.measureText(strPercent) / 2;            //计算字符串起始的  Y 坐标            //中心线到 bottom 的距离  = (fm.bottom - fm.top) / 2            //bottom 的 Y 坐标 = 中心线  + 中心线到 bottom 的距离            //baseline 的 Y 坐标 = bottom 的 Y 坐标 - fm.bottom            float strY = getWidth() / 2 + (fm.bottom - fm.top) / 2 - fm.bottom;            //绘制文字            //第二个参数是绘制起始的 x 坐标            //第三个参数是 baseline 的 Y 坐标            canvas.drawText(strPercent, strX, strY, paint);        }

这里写图片描述

5.绘制进度

绘制进度的弧形

        /*         * 进度         */        //设置抗锯齿        paint.setAntiAlias(true);        //设置画笔样式填充内部        paint.setStyle(Paint.Style.STROKE);        //设置颜色        paint.setColor(roundProgressColor);        //设置圆环宽度        paint.setStrokeWidth(roundWidth);        //传入圆形的左上右下四个边沿        RectF oval = new RectF(getWidth() / 2 - radius, getWidth() / 2 - radius,                 getWidth() / 2 + radius, getWidth() / 2 + radius);        //画进度条弧形        canvas.drawArc(oval, 0, 360 * progress / max, false, paint);

给自定义属性添加个设置进度方法,这样就可以在外部进行传值了。

    public void setProgress(int progress){        if (progress < 0) {            this.progress = 0;        } else if (progress > max) {            this.progress = max;        } else {            this.progress = progress;        }        postInvalidate();    }

这里写图片描述

6.添加样式

  <com.xiaoyue.circleprogressbar.CircleProgressBar        android:id="@+id/progressbar"        android:layout_width="100dip"        android:layout_height="100dip"        app:roundProgressColor="#ff00ff"        app:textColor="#666666"        app:textSize="20dp"        app:roundWidth="15dp"        />

这里写图片描述

三、附

代码链接:http://download.csdn.net/detail/qq_18983205/9852164

原创粉丝点击