Canvas与Drawable绘制图形

来源:互联网 发布:淘宝会员名是什么 编辑:程序博客网 时间:2024/05/19 14:36

一、图形展示

Android中提供两种方式来绘制图形到view上。

1.将Drawable(包括图片、动画等)绘制到view对象

如图片,图形,动画等,适用于一些实现简单且不需要动态改变的图形,比如动画,shape等。

Drawable是可绘制图形的抽象。其可以定义各种可绘制图形,包括ShapeDrawable、BitmapDrawable等等。当然也可以自定义一些drawable对象。

三种方式可以定义drawable:

1)使用图片

图片适用于应用程序图标,logo,icon等。

Android中图片支持三种,PNG,JPG,GIF,推荐用PNG,JPG适用于一些大的图片,比如启动页面的介绍图片,不推荐使用GIF,只会显示第一帧。

注意:构建时,通过appt工具可以无损压缩res/drawable中的资源。如不需要256色以上的真彩色PNG可以转换为8位PNG,这样图片质量相同,但是占用内存大大减少

如果想将文件作为bit流处理,则要放在res/raw中。

Resources res = mContext.getResources();Drawable myImage = res.getDrawable(R.drawable.my_image);

代码中获取图片。

注意,项目中每个唯一的资源都只有一个状态,如果同一图片实例化两个Drawable对象,更改其中一个也会影响另一个。

2)使用XML定义Drawable属性

在res/drawable目录中创建XML文件,通过Resources.getDrawable()根据ID来检索和实例化对象。

任何支持inflate()方法的Drawable的子类都可以在XML中定义。例子就不举了,shape、inset、animator都是。

3)在代码中创建

public class CustomDrawableView extends View {    private ShapeDrawable mDrawable;    public CustomDrawableView(Context context) {        super(context);        int x = 10;        int y = 10;        int width = 300;        int height = 50;        mDrawable = new ShapeDrawable(new OvalShape());        mDrawable.getPaint().setColor(0xff74AC23);        mDrawable.setBounds(x, y, x + width, y + height);    }    protected void onDraw(Canvas canvas) {        mDrawable.draw(canvas);    }}
这里给一个ShapeDrawable在代码中实现的例子。由于Drawable有自己的draw方法,因此在View的onDraw方法中,使用Drawable.draw()方法,并传递canvas。此处Drawable传递了一个OvalShpae,表示椭圆形的,然后设置了颜色,不设置则为黑色。同时设置了bounds,不设置就不会被绘制。

当然还有很多的drawable,比如BitmapDrawable、InsetDrawable、NinePatchDrawable等等,就不一一举例了。

2.使用canvas的各种draw方法来绘制图形

适用于需要定期重新绘制的图形,比如游戏画面,一些需要动态改变的图形,而且此时也可以控制动画。对于这种方式常用的方法有,在UI线程中通过invalidate()让系统回调onDraw()实现;或者是在子线程中在SurfaceView绘制。

在通过canvas绘制图形时,绘制的图其实是在底层bitmap上的,我们可以在onDraw()中直接绘制,或者在SurfaceView中通过SurfaceHolder.lockCanvas()获取Canvas。但如果创建一个新的Canvas,则需要定义新的Bitmap。上面说的两个可以直接绘制的,在View中其实已经设置好Bitmap了。如:

Bitmap b = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);Canvas c = new Canvas(b);

而这个Bitmap也可以绘制到其他的canvas上。

Canvas有一系列的draw方法。但是其他类也有一些draw方法,例如,drawable有自己的draw方法,用于将自身绘制到canvas上,只要将canvas作为参数传过去。

1)在View上绘制

如果不需要大量的计算和帧速率,应当考虑用自定义View。继承View或其子类,定义onDraw()方法,系统会调用它来绘制图形。在需要时,可以调用invalidate方法,表示想要重绘,但是系统并不保证及时的绘制。在子线程中使用postInvalidate()方法。

2)在SurfaceView上绘制

SurfaceView是View的特殊子类,在View层次结构中提供了一个专用绘图面。目的是在子线程进行绘制,而不用等待onDraw()。首先要继承SurfaceView,并实现SurfaceHolder.Callback,用于通知关于底层Surface的信息,以便知道何时开始绘制。


0 0
原创粉丝点击