android: Canvas的drawArc()方法的几个误区
绘制圆环很多时候会用到Canvas的drawArc方法,
drawArc()方法的说明很简单:
public void drawArc (RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
第一个参数 oval:定义承载圆弧形状的矩形。通过设置该矩形可以指定圆弧的位置和大小。
第二个参数 startAngle: 设置圆弧是从哪个角度顺时针绘画的。
第三个参数 sweepAngle: 设置圆弧顺时针扫过的角度。
第四个参数 useCenter: 绘制的时候是否使用圆心,我们绘制圆弧的时候设置为false,如果设置为true, 并且当前画笔的描边属性设置为Paint.Style.FILL的时候,画出的就是扇形。
第五个参数 paint: 指定绘制的画笔。
第一个误区:绘制的起始角度和扫过的角度
例:起始角度为-90,滑过角度为120度的圆环
canvas.drawArc(oval,-90,120,false,mPaint);
注意起始的-90度在上部的中点位置。
第二个误区:useCenter的作用
上面提过到,如果将画笔的样式设置为: mPaint.setStyle(Paint.Style.STROKE) 是看不出任何效果的。那么我们将画笔的样式设置为: mPaint.setStyle(Paint.Style.FILL) ,并分别将useCenter设置成false,true,观察下效果:
将useCenter设置为false,不经过圆心:
将useCenter设置为true,经过圆心:
第三个误区:如果该圆环有宽度,一定要注意绘制的起始位置
这点在使用drawCircle绘制时也需要注意:比如要画一个半径是50dip,路径宽度为6dip的圆,如果使用下列的代码去绘制:
mPaint.setColor(mDownloadBackgroundRingColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mDownloadBackgroundRingSize); float cx = mViewWidth / 2; float cy = mViewHeight / 2; float radius = mViewWidth / 2; canvas.drawCircle(cx, cy, radius, mPaint);
那么得到圆是这样子的:
注意到它的四边似乎少了一部分,这是因为一旦给圆设置了路径宽度,便需要该路径宽度也计算在内:所以这个圆的半径事实上应该是:View宽度/2 - 路径宽度/2, 只有这样才能容纳要绘制的View,否则多余的部分就看不见了。
将上面的代码修改成:
mPaint.setColor(mDownloadBackgroundRingColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mDownloadBackgroundRingSize); float cx = mViewWidth / 2; float cy = mViewHeight / 2; float radius = mViewWidth / 2 - mDownloadBackgroundRingSize / 2; canvas.drawCircle(cx, cy, radius, mPaint);
这样得到的圆就变成正常的了。
同样,如果圆环也有路径宽度,那么用于指定其位置的Rect也要注意绘制的起始位置。
// Draw background ring mPaint.setColor(mDownloadBackgroundRingColor); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(mDownloadBackgroundRingSize); float cx = mViewWidth / 2; float cy = mViewHeight / 2; float radius = mViewWidth / 2 - mDownloadBackgroundRingSize / 2; canvas.drawCircle(cx, cy, radius, mPaint); // Draw progress ring mPaint.setColor(mDownloadProgressBarColor); float margin = mDownloadBackgroundRingSize / 2; mDownloadBackgroundRingRect.set(margin, margin, mViewWidth - margin, mViewHeight - margin); canvas.drawArc(mDownloadBackgroundRingRect, -90, 90, false, mPaint);
下面这张图可能表达的更为清楚:
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库