Android开发之Paint的高级使用

前言:相信大家在绘制View的时候,对Paint使用已经不陌生了,今天我给大家总结一下Paint的用法,一些注意事项,以及Paint绘制文字的高级用法。

---------------------分割线-------------------

使用注意事项:

1.初始化画笔的时候要在init()里面初始化,切不可在onDraw里面初始化画笔

2.可以把固定不变的颜色、形状等在init里面初始化。

2.在onDraw里面操作画笔的时候记得paint.reset();重置一下。

---------------------分割线-------------------

在这里做总结一下paint常用的功能:

        //重置
        mPaint.reset();
        //给画笔设置颜色
        mPaint.setColor(Color.RED);
        //给画笔设置透明度
        mPaint.setAlpha(255);

        //设置画笔的样式
        mPaint.setStyle(Paint.Style.FILL);//填充内容
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setStyle(Paint.Style.STROKE);//描边
        //画笔的宽度
        mPaint.setStrokeWidth(50);
        //线帽
        mPaint.setStrokeCap(Paint.Cap.BUTT);//没有
        mPaint.setStrokeCap(Paint.Cap.ROUND);//圆的
        mPaint.setStrokeCap(Paint.Cap.SQUARE);//方形

	mPaint.setStrokeJoin(Paint.Join.MITER);//锐角
	mPaint.setStrokeJoin(Paint.Join.ROUND);//圆弧
	mPaint.setStrokeJoin(Paint.Join.BEVEL);//直线
------------------测试一:-----------------

画个实心圆测试一下效果:

        mPaint.setColor(Color.RED);
        canvas.drawCircle(100, 100, 100, mPaint);

效果图:(注意:默认效果是实心的)

其他形状可以自行设置

---------------------------测试二:--------------------------

可能你也注意到了,关于线帽和画笔样式有什么效果,ok我们使用Path来做一个小测试:

 mPaint.reset();
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);//描边
        mPaint.setStrokeWidth(50);
        mPaint.setStrokeCap(Paint.Cap.ROUND);//圆的
        //测试1
        Path path = new Path();
        path.moveTo(100, 100);
        path.lineTo(300, 100);
        path.lineTo(100, 300);
        mPaint.setStrokeJoin(Paint.Join.MITER);
        canvas.drawPath(path, mPaint);

        path.moveTo(100, 400);
        path.lineTo(300, 500);
        path.lineTo(100, 700);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        canvas.drawPath(path, mPaint);

        path.moveTo(100, 800);
        path.lineTo(300, 800);
        path.lineTo(100, 1100);
        mPaint.setStrokeJoin(Paint.Join.BEVEL);
        canvas.drawPath(path, mPaint);
效果图:

其他效果可以自行设置。

----------------------分割线----------------------------------

关于文字绘制的一些常用方法:
	//获得字符行间距
        mPaint.getFontSpacing();
        //获得字符之间的距离
        mPaint.getLetterSpacing();
        mPaint.getLetterSpacing(letterSpacing);//设置
        //设置文本删除线
        mPaint.setStrikeThruText(true);
        //是否设置下划线
        mPaint.setUnderlineText(true);
        //设置文本大小
        mPaint.setTextSize(textSize);
        mPaint.getTextSize();
        mPaint.setTypeface(Typeface.BOLD);//设置字体类型
//        Typeface.ITALIC;
//        Typeface.create(familyName,style);//加载自定义字体
        //文字倾斜 默认0,官方推荐的-0.25是斜体
        mPaint.setTextSkewX(-0.25f);
        //文本对齐方式
        mPaint.setTextAlign(Paint.Align.LEFT);
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaint.setTextAlign(Paint.Align.RIGHT);
        //计算制定长度的字符串(字符长度、字符个数、显示的时候真是的长度)
        int breadText = mPaint.breakText(text, measureForwards, maxWidth, measuredWidth);

        mPaint.setTextSize(50);
        float[] measuredWidth = new float[1];
	int breakText = mPaint.breakText(str, true, 200, measuredWidth);


        // Rect bounds获取文本的矩形区域(宽高)
	mPaint.getTextBounds(text, index, count, bounds)
	mPaint.getTextBounds(text, start, end, bounds)

	//获取文本的宽度,和上面类似,但是是一个比较粗略的结果
	float measureText = mPaint.measureText(str);
	//获取文本的宽度,和上面类似,但是是比较精准的。
	float[] measuredWidth = new float[10];

	//measuredWidth得到每一个字符的宽度;textWidths字符数
	int textWidths = mPaint.getTextWidths(str, measuredWidth);
以上皆是绘制文字的常用api,大家可以自行测试。

--------------------------分割线-----------------------

关于文本Metrics的使用(重点、难点):

 mPaint.setTextSize(80);
        mPaint.setTextAlign(Paint.Align.LEFT);
        mPaint.setColor(Color.BLUE);
        canvas.drawText(str, 0, 200, mPaint);

        //文本Metrics
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        float top = fontMetrics.top;
        float ascent = fontMetrics.ascent;
        float descent = fontMetrics.descent;
        float bottom = fontMetrics.bottom;
        float leading = fontMetrics.leading;

        Log.i("--top-->", top + "");
        Log.i("--ascent-->", ascent + "");
        Log.i("--descent-->", descent + "");
        Log.i("--bottom-->", bottom + "");
        Log.i("--leading-->", leading + "");
我们设置的文本 坐标是(0,200)文本大小是80,。

ok看下我们获取的top、ascent、descent、bottom、leading值

ok由此我们可以简单得出的是leading值为0,leading上为负数,下面为正数,然后在根据文本坐标,我们可以得到top,ascent,descent,bottom,和leading的线:

	mPaint.setColor(Color.BLUE);
        canvas.drawLine(0, 200 + top, 2000, 200 + top, mPaint);//top线

        mPaint.setColor(Color.BLACK);
        canvas.drawLine(0, 200 + ascent, 2000, 200 + ascent, mPaint);//ascent线

        mPaint.setColor(Color.RED);
        canvas.drawLine(0, 200 + leading, 2000, 200 + leading, mPaint);//leading或baselineY

        mPaint.setColor(Color.BLUE);
        canvas.drawLine(0, 200 + descent, 2000, 200 + descent, mPaint);//descent线

        mPaint.setColor(Color.BLACK);
        canvas.drawLine(0, 200 + bottom, 2000, 200 + bottom, mPaint);//bottom线

如图所示:

ok这里得出一个疑惑点,字体的中间线如何获取,想获取中线线其实求出中间线的y坐标即可!

根据图所示,我们可以分析出center线在descent线和ascent线的中间(如有错误,欢迎指出)。

获取中间线的坐标,我们必须先获取字体的真实高度:

 	//字体高度
        float textHeight = (200 + descent) - (200 + ascent);
        Log.i("--textHeight-->", textHeight + "");
然后获取center线的坐标:
        //中间
        float centerY = (descent - textHeight / 2) + 200;
        mPaint.setColor(Color.RED);
        canvas.drawLine(0, centerY, 2000, centerY, mPaint);//center线
ok这样的话我们就找到了文字的关键的几个线了,我们就可以自由的利用这些线进行各种操作了。

----------------------------完--------------------------

发布了129 篇原创文章 · 获赞 83 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_32306361/article/details/72869936