从今天开始介绍ApiDemos中与图形相关的例子。Android 平台提供了功能强大的2D ,3D Graphics 以及动画支持。如果你具有Windows GDI+开发背景,只要了解Android 2D于GDI之间的对应关系也就很快容易上手。如果你还是喜欢GDI的风格,引路蜂软件也提供了一个免费平台无关的高效二维图形库,有兴趣的可以参见Android简明开发教程二十四:总结及示例代码下载和Silverlight 引路蜂二维图形库示例。

在开始学习Android Graphics开发之前,我们先简要介绍一下Android 2D Graphics 中最重要的几个类:

Canvas: 用于定义一个画板,所有的绘图操作都发生在这个Canvas对象上。它主要提供了:

  • 绘制基本几何图形,如Shape和Path。
  • 绘制图像bitmaps。
  • 绘制文字。
  • 图形裁剪。
  • 图形坐标变换等。

Paint: 可以看作绘图时所有的调色板,它定义了绘制时所用的画刷,画笔,颜色,字体等对应于GDI的的Brush,Color,Pen,Font 等绘图属性。

Bitmap: 每个Canvas对应一个Bitmap,用于存储Canvas的绘制结果(像素值)。Android也提供里方法来直接操作Bitmap中的像素。

因此在Android要绘制一个东西,需要四个部分:一个Bitmap用于存储像素值,一个Canvas用于定义绘图操作,一个Paint定义绘图使用的颜色,画笔,画刷等属性,最后一个是要绘制的图形本身(如矩形,线段等)。

一般来说,如果需要在屏幕上绘制图形,可以从View 派生一个子类,重载view 的onDraw(Canvas canvas)方法。onDraw会在每次刷新屏幕时执行。在onDraw中可以使用传入的canvas对象绘制需要的图形。

示例AlphaBitmap 使用到 Bitmap, Shader ,Canvas ,Paint 等类,主要用于演示图形Alpha通道,Alpha通道指的是图像的透明度。

mBitmap2 = mBitmap.extractAlpha();

mBitmap2 为使用extractAlpha 只取出mBitmap 的Alpha通道,对应一个图像来说,mBitmap2可以理解为这个图像的Mask部分,表示这部分有图像内容。如本例红色的部分为ApiDemos图标的Mask,为ApiDemos图标的轮廓。

Shader 可以理解为GDI中的画刷类,本例定义了一个线性渐变画刷:

mShader = new LinearGradient(0, 0, 100, 70, new int[] {
 Color.RED, Color.GREEN, Color.BLUE },
 null, Shader.TileMode.MIRROR);

在区域(0,0)-(100,70)内以三色红,绿,蓝均匀线性渐变。

再来看看mBitmap3 的绘制

mBitmap3 = Bitmap.createBitmap(200, 200,
 Bitmap.Config.ALPHA_8);
drawIntoBitmap(mBitmap3);
 ...
private static void drawIntoBitmap(Bitmap bm) {
 float x = bm.getWidth();
 float y = bm.getHeight();
 Canvas c = new Canvas(bm);
 Paint p = new Paint();
 p.setAntiAlias(true);
 
 p.setAlpha(0x80);
 c.drawCircle(x/2, y/2, x/2, p);
 
 p.setAlpha(0x30);
 p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
 p.setTextSize(60);
 p.setTextAlign(Paint.Align.CENTER);
 Paint.FontMetrics fm = p.getFontMetrics();
 c.drawText("Alpha", x/2, (y-fm.ascent)/2, p);
}

mBitmap3 不是从资源文件中读取,而是通过代码生成,Bitmap.Config.ALPHA_8 只像素作为单独的Alpha通道存储,通常是作为其它图像的Mask Bitmap来使用。

Canvas c = new Canvas(bm); 可以为Bitmap创建一个Canvas对象,所有在这Canvas上绘制的图像最终会存储在对应的Bitmap中,一般在Double Buffer或者想在后台绘制图形使用setAlpha 设置当前Paint的Alpha(透明度)值,0 为全透明,255为不透明。之间的值部分透明,Alpha值越大,透明度越低。

Paint 除了设置透明度之外,还可以设置字体大小,Shader等属性。

最后看看onDraw(Canvas canvas)的代码:

canvas.drawColor(Color.WHITE);
 
Paint p = new Paint();
float y = 10;
 
p.setColor(Color.RED);
canvas.drawBitmap(mBitmap, 10, y, p);
y += mBitmap.getHeight() + 10;
canvas.drawBitmap(mBitmap2, 10, y, p);
y += mBitmap2.getHeight() +10;
p.setShader(mShader);
canvas.drawBitmap(mBitmap3, 10, y, p);

最左上角显示ApiDemo的图标mBitmap。 mBitmap2 中存储了mBitmap中的Alpha通道值,此是如果调用Canvas.drawBitmap(mBitmap2),mBitmap2 的颜色会显示由Paint传入的值(此例为红色),有兴趣的可以改为其它颜色试试,mBitmap2的颜色也会随着变化。对于mBitmap3 来说 ,drawIntoBitmap中只绘制了一个圆和一行文字,但由于创建时采用的是ALPHA_8配置,因此和mBitmap2类似,它也会使用有Paint定义的颜色,但Paint此时定义的颜色是由Shader定义颜色线性渐变,所以就有了五颜六色的背景。