自定义view 系列二 text相关方法

虽然介绍的是有关draw text的相关方法,但是一些属性设置还是通过Paint 来设定,毕竟text还是paint  画出来的。

一、paint的方法、canvas.drawText方法以及Typeface的使用

1. paint的方法介绍

        Paint.Style.FILL:填充内部
        Paint.Style.FILL_AND_STROKE  :填充内部和描边
        Paint.Style.STROKE  :描边*/
        setUnderlineText(true):设置下划线
        setStrikeThruText(true):设置删除线
        setTextSkewX(float  skewX):倾斜度, - 左,+右
        setTextScaleX(float scaleX):整数为水平伸长
        //drawText  以及样式
        mPaint.setStyle(Paint.Style.STROKE);       //字体中间不填充
        canvas.drawText("一篇诗,一斗酒,一曲长歌,一剑天涯", 100, 100, mPaint);

        mPaint.setStyle(Paint.Style.FILL);         //字体填充
        canvas.drawText("一篇诗,一斗酒,一曲长歌,一剑天涯", 100, 250, mPaint);

        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);  //字体填充
        canvas.drawText("一篇诗,一斗酒,一曲长歌,一剑天涯", 100, 400, mPaint);

        mPaint.setUnderlineText(true);   //设置下划线
        mPaint.setStrikeThruText(true);  //设置删除线
        mPaint.setTextSkewX((float) -0.25);  //倾斜度  - 左, + 右
        canvas.drawText("一篇诗,一斗酒,一曲长歌,一剑天涯", 100, 550, mPaint);

        mPaint.setTextScaleX(2);   //水平拉伸原来的2倍(上一次样式的2倍)
        mPaint.setColor(Color.BLUE);
        canvas.drawText("一篇诗,一斗酒,一曲长歌,一剑天涯", 1, 5, 100, 700, mPaint);  //  0开始不包含5   篇诗,一
效果图如下




2. canvas drawText

public void drawText(String text, float x, float y, Paint paint)
根据x, y坐标开始绘制第一个字

public void drawText(String text, int start, int end, float x, float y, Paint paint)
根据x, y坐标绘制,并且使用start end来截取text中的文字

public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint)
根据path路径进行绘制
 float hOffset  : 与路径起始点的水平偏移距离
 float vOffset  : 与路径中心的垂直偏移量

public void drawPosText(String text, float[] pos, Paint paint)
根据pos提供的点(2个一组),进行绘制
注意:pos中的点数不能小于text的长度,不然会报java.lang.IndexOutOfBoundsException;所以在使用时要注意
ps: 这边列举了主要的方法,还有其他方法与上方的区别是传入的字符串类型不一样,可能是char[], CharSequence, string
        float[] pos = {80, 80, 200, 1050, 250, 80, 234, 456, 240, 300, 400, 500, 900, 600};
        canvas.drawPosText("但愿长醉不复醒", pos, mPaint);   //根据位置来写每个字
        //canvas.drawPosText("一篇诗,一斗酒,一曲长歌,一剑天涯".toCharArray(), 2, 4, pos, mPaint);
        mPaint.setColor(Color.GREEN);
        //drawOnPath
        RectF mRectF = new RectF(100, 100, 600, 500);
        Path mPath = new Path();
        mPath.addOval(mRectF, Path.Direction.CW); //顺时针
        canvas.drawTextOnPath("一篇诗,一斗酒,一曲长歌,一剑天涯", mPath, 0, 0, mPaint);

效果图如下:


3. Typeface 的使用

Typeface 是用来设置字体样式的,除了系统的字体,还有自定义的.ttf的字体使用
创建Typeface:  可指定系统或自定义的字体进行设置
        Typeface create(String familyName, int style) //直接通过指定字体名来加载系统中自带的文字样式
        Typeface create(Typeface family, int style)     //通过其它Typeface变量来构建文字样式
        Typeface createFromAsset(AssetManager mgr, String path) //通过从Asset中获取外部字体来显示字体样式
        Typeface createFromFile(String path)//直接从路径创建
        Typeface createFromFile(File path)//从外部路径来创建字体样式
        Typeface defaultFromStyle(int style)//创建默认字体


        上面的几个个参数会用到Style变量,Style的枚举值如下:
        Typeface.NORMAL  //正常体
        Typeface.BOLD //粗体
        Typeface.ITALIC //斜体
        Typeface.BOLD_ITALIC //粗斜体

        Typeface font = Typeface.create("宋体", Typeface.NORMAL);
        mPaint.setTypeface(font);
        mPaint.setTextSize(100);
        canvas.drawText("Aa", 80, 200, mPaint);

        Typeface font1 = Typeface.createFromAsset(getContext().getAssets(), "DancingScript-Bold.ttf");
        mPaint.setTypeface(font1);
        canvas.drawText("Aa", 80, 400, mPaint);

效果图如下:




二、drawText中的须知特点

当我们使用public void drawText(String text, float x, float y, Paint paint)时,实验我们设置为(0,0),此时我们是看不到文字的;
这是因为,设置的x, y 其实是设置的一条基线,x,y 为顶点,y为高的直线,就像小时候写英语单词的4线格的第三条,而不是左上角的顶点。
为了能够写好文字,android中提供了如下几条线:

        baseline: 基线,开发这自己定义的
        ascent:   系统建议的,绘制单个字符时,字符应当的最高高度所在线
        descent:  系统建议的,绘制单个字符时,字符应当的最低高度所在线
        top:      可绘制的最高高度所在线
        bottom:   可绘制的最低高度所在线

1. 画一条基线

setTextAlign,指定点在文字的相对位置
下面代码表示的是在(300, 500)绘制的文字以及一条直线
Paint paint_line = createPaint(Color.RED, Paint.Style.STROKE, 5);
        canvas.drawColor(Color.BLACK);
        int x = 300;
        int y = 500;
        canvas.drawLine(x, y, 1800, 500, paint_line);
//        paint_text.setTextAlign(Paint.Align.CENTER); //文字的中间位置在指定点
        paint_text.setTextAlign(Paint.Align.LEFT); //默认情况,文字的左边在指定点
//        paint_text.setTextAlign(Paint.Align.RIGHT);  //以文字的右边在指定点
        canvas.drawText("HaaaAgfj", 300, 500, paint_text);
运行结果如下: 指定点在文字的左侧,并且红色就是基线



2. 如何判断其他线的位置

基线baseline是由drawText的x, y 坐标决定的。
当baseline 位置决定后,其他4条线也就可以计算出来。
android 提供了Paint.FontMetrics text_meterics = paint_text.getFontMetrics();  
public static class FontMetrics {
        public float ascent;
        public float bottom;
        public float descent;
        public float leading;
        public float top;
        public FontMetrics() {
            throw new RuntimeException("Stub!");
        }
    }

所以我们获得的基线是有正有负的,因为他的计算方法如下。
ascent = ascent线的y坐标 - baseline线的y坐标;
descent = descent线的y坐标 - baseline线的y坐标;
top = top线的y坐标 - baseline线的y坐标;
bottom = bottom线的y坐标 - baseline线的y坐标;

根据上面公式,几条线的y坐标就能计算得出,那么下面我们画出其他几条线:
Paint.FontMetrics text_meterics = paint_text.getFontMetrics();
        int top = (int) (y + text_meterics.top);
        int ascent = (int) (y + text_meterics.ascent);
        int descent = (int) (y + text_meterics.descent);
        int bottom = (int) (y + text_meterics.bottom);


        canvas.drawLine(x, top, 1800, top, paint_line);
        canvas.drawLine(x, ascent, 1800, ascent, paint_line);
        canvas.drawLine(x, bottom, 1800, bottom, paint_line);
        paint_line.setColor(Color.BLUE);
        canvas.drawLine(x, descent, 1800, descent, paint_line);
其中bottom和descent的距离比较近,效果图如下:





3. 绘制文字矩形

1. 绘制文字的区域 
    上面计算出top 以及 bottom 这里只要计算出文字的宽度Paint.measureText.
        int textWidth = (int) paint_text.measureText("HaaaAgfj");
        Rect mRect = new Rect(x, top, x + textWidth, bottom);
        canvas.drawRect(mRect, paint_line);

2. 绘制文字的当前区域
可通过getTextBounds获得在基线y=0时候的矩形各点坐标
        Paint paint_rect = createPaint(Color.BLUE, Paint.Style.STROKE, 5);
        Rect minRect = new Rect();
        paint_rect.getTextBounds("HaaaAgfj",0,"HaaaAgfj".length(),minRect); //paint.getTextBounds()得到基线为y=0的最小矩形的各点坐标
        minRect.top = y + minRect.top;
        minRect.bottom = y + minRect.bottom;
        minRect.left = x;
        minRect.right = x + textWidth;
        canvas.drawRect(minRect,paint_rect);
效果如下:



猜你喜欢

转载自blog.csdn.net/weixin_39158738/article/details/77480415
今日推荐