第 1 章
绘图基础
迷茫,本就是青春该有的样子,但不要让未来的你讨厌现在的自己。
本章作为开篇第 1 章,主要讲解有关自定义控件系列的一些基础知识,是后续各章节
的根基。
1.1 基本图形绘制
1.1.1 概述
我们平时画图需要两个工具:纸和笔。在 Android 中,Paint 类就是画笔,而 Canvas 类就
是纸,在这里叫作画布。
所以,凡是跟画笔设置相关的,比如画笔大小、粗细、画笔颜色、透明度、字体的样式
等,都在 Paint 类里设置;同样,凡是要画出成品的东西,比如圆形、矩形、文字等,都调用
Canvas 类里的函数生成。
下面通过一个自定义控件的例子来看一下如何生成自定义控件,以及 Paint 和 Canvas 类
的用法。
(1)新建一个工程,然后写一个类派生自 View。
package com.harvic.PaintBasis;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class BasisView extends View {
public BasisView(Context context) {
super(context);
}
Android 自定义控件开发入门与实战
public BasisView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public BasisView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//设置画笔的基本属性
Paint paint=new Paint();
paint.setColor(Color.RED); //设置画笔颜色
paint.setStyle(Paint.Style.STROKE); //设置填充样式
paint.setStrokeWidth(50); //设置画笔宽度
//画圆
canvas.drawCircle(190, 200, 150, paint);
}
}
代码很简单,首先,写一个类派生自 View。派生自 View 表示当前是一个自定义的控件,
类似 Button、 TextView 这些控件都是派生自 View 的。如果我们想像 LinearLayout、
RelativeLayout 这样生成一个容器,则需要派生自 ViewGroup。有关 ViewGroup 的知识,我们
会在后面的章节中讲述。
其次,重写 onDraw(Canvas canvas)函数。可以看到,在该函数中,入参是一个 Canvas
对象,也就是当前控件的画布,所以我们只要调用 Canvas 的绘图函数,效果就可以直接显
示在控件上了。
在 onDraw(Canvas canvas)函数中,我们设置了画笔的基本属性。
Paint paint=new Paint();
paint.setColor(Color.RED); //设置画笔颜色
paint.setStyle(Paint.Style.STROKE); //设置填充样式
paint.setStrokeWidth(50); //设置画笔宽度
在这里,我们将画笔设置成红色,填充样式为描边,并且将画笔的宽度设置为 50px(有
关这些属性的具体含义,会在后面一一讲述)。
最后,我们利用
canvas.drawCircle(190, 200, 150, paint);语句画了一个圆。需要
注意的是,画圆所用的画笔就是我们在这里指定的。
(2)使用自定义控件。
我们可以直接在主布局中使用自定义控件(main.xml)。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
2
第 1 章 绘图基础
<com.harvic.PaintBasis.BasisView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
可以看到,在 XML 中使用自定义控件时,需要使用完整的包名加类包的方式来引入。注
意:这里的布局方式使用的全屏方式。后面会讲到如何给自定义控件使用 wrap_content 属性,
目前我们全屏显示控件即可。
效果如下图所示。
从这里可以看到,只需要先创建一个派生自 View 的类,再重新在 onDraw()函数中设置
Paint 并调用 Canvas 的一些绘图函数,就可以画出我们想要的图形。由此看来,自定义控件并
不复杂。下面我们分别来看如何设置画笔,以及 Canvas 中常用的一些绘图函数。
1.1.2 画笔的基本设置
我们初步讲一下 1.1.1 节的示例中所涉及的几个函数。
1.setAntiAlias()
该函数的具体声明如下:
void setAntiAlias(boolean aa)
表示是否打开抗锯齿功能。抗锯齿是依赖算法的,一般在绘制不规则的图形时使用,比
如圆形、文字等。在绘制棱角分明的图像时,比如一个矩形、一张位图,是不需要打开抗锯
齿功能的。
下面绘制一个实体圆形,抗锯齿功能分别在打开和关闭的情况下效果如下图所示。
很明显,在打开抗锯齿功能的情况下,所绘图像可以产生平滑的边缘。
其中,打开抗锯齿功能的代码如下:
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint=new Paint();
paint.setColor(Color.RED); //设置画笔颜色
paint.setStyle(Paint.Style.FILL); //设置填充样式
3
Android 自定义控件开发入门与实战
paint.setAntiAlias(true); //打开抗锯齿功能
paint.setStrokeWidth(50); //设置画笔宽度
//画圆
canvas.drawCircle(190, 200, 150, paint);
}
2.setColor()
该函数的作用是设置画笔颜色,完整的函数声明如下:
void setColor(int color)
我们知道,一个颜色值是由红、绿、蓝三色合成出来的,所以,参数 color 只能取 8 位的
0xAARRGGBB 样式颜色值。
其中:
A 代表透明度(Alpha),取值范围是 0~255(对应十六进制的 0x00~0xFF),取值越
小,透明度越高,图像也就越透明。当取 0 时,图像完全不可见。
R 代表红色值(Red),取值范围是 0~255(对应十六进制的 0x00~0xFF),取值越小,
红色越少。当取 0 时,表示红色完全不可见;当取 255 时,红色完全显示。
G 代表绿色值(Green),取值范围是 0~255(对应十六进制的 0x00~0xFF),取值越
小,绿色越少。当取 0 时,表示绿色完全不可见;当取 255 时,绿色完全显示。
B 代表蓝色值(Blue),取值范围是 0~255(对应十六进制的 0x00~0xFF),取值越小,
蓝色越少。当取 0 时,表示蓝色完全不可见;当取 255 时,蓝色完全显示。
比如 0xFFFF0000 就表示大红色。因为透明度是 255,表示完全
不透明,红色取全量值 255,
其他色值全取 0,表示颜色中只有红色;当然,如果我们不需要那么红,则可以适当减少红色
值,比如 0xFF0F0000 就会显示弱红色。当表示黄色时,由于黄色是由红色和绿色合成的,所
以 0xFFFFFF00 就表示纯黄色。当然,如果我们需要让黄色带有一部分透明度,以便显示出
所画图像底层图像,则可以适当减少透明度值,比如 0xABFFFF00;当透明度减少到 0 时,
任何颜色都是不可见的,也就是图像变成了全透明,比如 0x00FFFFFF,虽然有颜色值,但由
于透明度是 0,所以整个颜色是不可见的。
其实,除手动组合颜色的方法以外,系统还提供了一个专门用来解析颜色的类——Color
(有关 Color 类的使用,我们稍后将在本章中提及)。
下面绘制一大一小两个圆,并且将这两个圆叠加起来,上方的圆半透明,代码如下:
Paint paint=new Paint();
paint.setColor(0xFFFF0000);
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(50);
canvas.drawCircle(190, 200, 150, paint);
paint.setColor(0x7EFFFF00);
canvas.drawCircle(190, 200, 100, paint);
这里绘制了两个圆,第一个圆的颜色值是 0xFFFF0000,即不透明的红色,半径取 150px;
第二个圆的颜色值是 0x7EFFFF00,即半透明的黄色,半径取 100px。效果如下图所示。
4
第 1 章 绘图基础
扫码看彩色图
3.setStyle()
完整的函数声明如下:
void setStyle(Style style)
该函数用于设置填充样式,对于文字和几何图形都有效。style 的取值如下。
Paint.Style.FILL:仅填充内部。
Paint.Style.FILL_AND_STROKE:填充内部和描边。
Paint.Style.STROKE:仅描边。
设置填充内部及描边的样式代码如下:
Paint paint=new Paint();
paint.setColor(0xFFFF0000);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(50);
canvas.drawCircle(190, 200, 150, paint);
下面以绘制的一个圆形为例,看一下这三个类型的不同,效果如下图所示。
明显可见,FILL_AND_STROKE 是 FILL和 STROKE叠加在一起显示的结果,FILL_AND_
STROKE 比 FILL 多了一个描边的宽度。
4.setStrokeWidth()
完整的函数声明如下:
void setStrokeWidth(float width)
用于设置描边宽度值,单位是 px。当画笔的 Style 样式是 STROKE 和 FILL_AND_STROKE
时有效。
有关该函数的使用,在上面的例子中已经多次涉及,这里就不再举例了。
1.1.3 Canvas使用基础
前面介绍了 Paint 的基本设置方法,下面再来讲讲有关 Canvas 绘图的知识。
5