Android 自定义View 画圆(奥运五环)
你会画画吗?你会写代码吗?你会用代码画画吗?
自定义View,在实际开发过程中需要考虑用户体验时往往会引入一些花里胡哨的功能(我们常说的骚操作),此时面临两种方案:你更倾向于使用GIF还是自行设计?使用GIF无疑会导致APP体积增大(而且维护成本也很高),自行设计同样面临较大的挑战(这也是为什么很多人选择先用GIF解决问题)。不过即便解决了表层问题还需深入探索(PS:过去我也曾这么认为),但随着经验的增长(小老弟),事情总会有新认识。
下面正式进入创作环节。
思考一个问题:用什么来画?显而易见的是纸和笔。那么,在程序中如何实现这一功能呢?如何将绘制好的图形展示到页面上呢?你是否也会好奇这些问题的答案呢?下面一一解答你的疑问:在Android开发中,默认使用Paint工具来完成绘图工作;所谓的Canvas其实就是绘图区域的容器;那么到底是什么让这些图形能够以直观的方式呈现出来呢?这些问题的答案或许会使你对移动开发产生更深的兴趣吧!
随后的问题:哪些类型的图像能被绘制出来?
Paint
这个即为绘图工具。在Android应用中通常称为绘画工具。你可以调整绘图工具的颜色设置。以下是关于该绘图工具属性的详细表格。
|属性|说明|
|—|—|
setAntiAlias|设置画笔的抗锯齿效果参数。当参数设置为true时会关闭抗锯齿效果;如果参数设置为false,则不会关闭该效果。默认情况下会有抗锯齿效果存在,并且通常情况下能提高绘图效率。
|setColor|设置画笔颜色|
setARGB
|setAlpha|设置alpha不透明度,范围为0~255|
|setFakeBoldText|设置为粗体文本|
|setLinearText|设置为线性文本|
|setTextAlign|设置文本对齐方式|
|setTextSize|设置字体尺寸|
|setTextScaleX|设置文本缩放倍数,1.0f为原始|
指定字体为SetTypeface()。该参数包含了几种属性:样式(包括了字体的类型)、宽度以及还包括了倾斜和其他属性如颜色等。
|setUnderlineText|设置下划线|
|setStyle|配置画笔样式 ,包括常见的 (Paint..) (实心)、 (Paint..) (空心)、 (Paint..) (填充加描边)
|setStrokeWidth|在画笔的样式为STROKE的时候,图形的轮廓宽度|
这也算是一种属性吧?因为担心您无法耐烦看完这些内容而选择简略处理。不过既然上面已经讲完了笔的相关知识的话,下面就要转向讨论纸张的内容了。
Canvas
这个Drawable在Android中被称作绘图板;那么它具体有哪些属性呢?也可以用表格的形式来详细列出这些属性。
|属性|说明|
|—|—|
|drawARGB|画布颜色,第一个是透明度,后面是常规的RGB色值|
|drawColor|画布颜色,可以用Android自带的,也可以自定义|
|drawRGB|画布颜色,相比drawARGB少了一个透明度而已|
|drawArc|扇形|
|drawCircle|圆形|
|drawOval|椭圆形|
|drawLine|线|
|drawPoint|点|
|drawRect|矩形|
|drawRoundRect|圆角矩形|
|drawVertices|顶点|
|drawPath|路径|
|drawBitmap|位图|
|drawPicture|图片|
明白啦!觉得这个表格有点让人头疼呢。(补充一下)其实我也觉得写起来挺费劲的哦。充满期待地想动手操作起来呢。接下来就开始动手实践吧。
为了更好地进行后续操作,我首先为项目命名了PaintDemo,并确保其已正确创建。随后,在项目根目录下新建了一个名为CustomView.java的Java文件,并使其继承自View类。接下来的任务是实现两个必要的构造方法。如需进一步了解,请参考以下代码片段:

然后我们会在activity_main.xml中调用该Custom以实现自定义View功能,在运行时请确保使用的包名路径完整无误

如果你现在运行程序的话,并且无论是实际运行在真机上还是在虚拟环境中运行,请先确认项目的各项设置是否正确无误。建议你在开始测试之前先确认项目的各项设置是否正确无误。从而减少因环境差异导致的问题排查工作量。这是实际开发总结出来的经验教训之一。需要注意的是,在完成上述步骤后执行测试时,在屏幕上会出现一片空白区域。
下面在CustomView写下如下代码
/**
在纸上画画 (通俗理解)
@param canvas 纸
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();//创建画笔对象 笔
paint.setColor(Color.BLACK);//设置颜色
paint.setStyle(Paint.Style.STROKE);//画笔样式为空心,也可以理解为描边
paint.setStrokeWidth(4);//描边的宽度
paint.setAntiAlias(true);//抗锯齿(去掉锯齿)
/**
画圆
参数一:圆心的X轴坐标
参数二:圆心的Y轴坐标
参数三:圆的半径
参数四:画笔对象
*/
canvas.drawCircle(150,150,100,paint);//完成
}
据我所知, 注释已经非常清楚了. 执行一次后, 结果就是能看到一个黑色的空心圆.

然后再修改一下代码,画一个实心圆

再运行一下

**canvas.drawCircle(150, 150, 100, paint);**具体说明圆心位于横坐标和纵坐标均为150的位置,并以半径为100绘制一个圆形。通过复制该行代码四次即可生成四个相同的圆形。为了观察到效果,请确保每个圆形都是空心的。

然后运行一下,就可以看到

是不是感觉挺有意思的?通常面对这类图案时,你会选择自行绘制吗?还是会倾向于使用UI素材库来获取这些元素呢?
刚才我们只是改变了半径而已,下面试着改变横坐标和纵坐标。
为了便于观察两个圆相切的情况, 我们尝试绘制两个相邻的圆形物体. 当两物体水平相切时, 则需确保其中一个物体中心点所在平面直角坐标的x值等于另一物体中心点所在平面直角坐标的x值与两者直径之和. 上一例中观察到第一个物体中心位于x=150的位置, 其半径r=100. 因此可以确定第二个物体中心应位于x=350处. 本次实验中保持两者的半径不变, 在此前提下仅调整第一个物体的位置进行测试.

运行结果如下图

接下来运用这个思路来画一个奥运五环吧

运行效果如下图所示

除了无色以外还是比较像的。如果你希望更改颜色的话就能随意修改 setColor 了。稍后我们来调整代码部分
/**
根据传入的颜色配置不同的画笔
@param color 颜色
@return
*/
private Paint customPaint(int color){
Paint paint = new Paint();//创建画笔对象 笔
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(8);
paint.setAntiAlias(true);
return paint;
}
然后我们在onDraw中调用
/**
在纸上画画 (通俗理解)
@param canvas 纸
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
