本文地址:http://blog.csdn.net/scarthr/article/details/42524599
SurfaceView是一个可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView。
一 SurfaceView的使用
我们创建一个MyView继承SurfaceView,实现SurfaceHolder.Callback接口。
- package com.thr.testsurfaceview;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class MyView extends SurfaceView implements SurfaceHolder.Callback {
-
- public MyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- getHolder().addCallback(this);
- }
-
- public void draw() {
-
- Canvas canvas = getHolder().lockCanvas();
-
-
- getHolder().unlockCanvasAndPost(canvas);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
-
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
-
- draw();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
-
- }
- }
这个SurfaceHolder相当于Surface的一个控制器,用它来控制SurfaceView的大小,图形等等。
注意这个draw方法要在Surface创建后调用,在被销毁前结束。
二 使用SurfaceView绘制图形
我们在构造方法中设置好画笔的颜色,draw方法里画图就可以了:
- package com.thr.testsurfaceview;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class MyView extends SurfaceView implements SurfaceHolder.Callback {
-
- private Paint paint;
-
- public MyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- paint = new Paint();
- paint.setColor(Color.RED);
- getHolder().addCallback(this);
- }
-
- public void draw() {
-
- Canvas canvas = getHolder().lockCanvas();
- canvas.drawColor(Color.WHITE);
- canvas.drawRect(0, 0, 100, 100, paint);
-
- getHolder().unlockCanvasAndPost(canvas);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
-
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
-
- draw();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
-
- }
- }
然后在Activity中setContentView时直接设置我们的MyView就可以看到效果了。
三 绘制组合图形
我们创建这样一个容器类:
- package com.thr.testsurfaceview;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import android.graphics.Canvas;
-
- public class Container {
-
- private List<Container> children;
-
- public Container() {
- children = new ArrayList<Container>();
- }
-
- public void draw(Canvas canvas) {
- childrenDraw(canvas);
- for (Container c : children) {
- c.draw(canvas);
- }
- }
-
- public void childrenDraw(Canvas canvas) {
-
- };
-
- public void addChildrenView(Container child) {
- children.add(child);
- }
-
- public void removeChildrenView(Container child) {
- children.remove(child);
- }
- }
它有添加
和移除子控件的方法,draw方法是以此调用子控件的childrenDraw方法,如果还有子
控件,再调子控件的children方法。
在创建一个画圆和正方形的类,都继承自Container:
- package com.thr.testsurfaceview;
-
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
-
- public class Circle extends Container {
- private Paint paint;
-
- public Circle() {
- paint = new Paint();
- paint.setColor(Color.RED);
- }
-
- @Override
- public void childrenDraw(Canvas canvas) {
- canvas.drawCircle(50, 50, 50, paint);
- }
- }
- package com.thr.testsurfaceview;
-
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
-
- public class Rect extends Container {
-
- private Paint paint;
-
- public Rect() {
- paint = new Paint();
- paint.setColor(Color.BLUE);
- }
-
- @Override
- public void childrenDraw(Canvas canvas) {
- canvas.drawRect(0, 0, 100, 100, paint);
- }
- }
最后是GameView类,继承自SurfaceView:
- package com.thr.testsurfaceview;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class GameView extends SurfaceView implements SurfaceHolder.Callback {
-
- private Container container;
- private Rect rect = new Rect();
- private Circle circle = new Circle();
-
- public GameView(Context context, AttributeSet attrs) {
- super(context, attrs);
- container = new Container();
- rect = new Rect();
- circle = new Circle();
- rect.addChildrenView(circle);
- container.addChildrenView(rect);
- getHolder().addCallback(this);
- }
-
- public void draw() {
- Canvas canvas = getHolder().lockCanvas();
- container.draw(canvas);
- getHolder().unlockCanvasAndPost(canvas);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- draw();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
- }
用Container包含了一个矩形,矩形又包含了一个圆,运行效果:
接下来我们让这个创建的图形移动起来。
我们在Container中添加成员变量x、y,用来记录绘图坐标。
修改Container的draw方法:
- public void draw(Canvas canvas) {
-
- canvas.translate(getX(), getY());
- childrenDraw(canvas);
- for (Container c : children) {
- c.draw(canvas);
- }
-
- }
在Rect的childrenDraw方法中,对坐标进行改变:
- setX(getX() + 1);
- setY(getY() + 2);
在GameView中加入定时器,每隔100毫秒重新绘制一次图形,达到图形移动的效果。
- private TimerTask task;
- private Timer timer;
-
- public void startTimer() {
- timer = new Timer();
- task = new TimerTask() {
-
- @Override
- public void run() {
- draw();
- }
- };
- timer.schedule(task, 100, 100);
- }
-
- public void stopTimer() {
- if (timer != null) {
- timer.cancel();
- timer = null;
- }
-
- }
在创建SurfaceView的时候启动定时器,在销毁SurfaceView的时候取消定时器。
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- startTimer();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- stopTimer();
- }
源码下载
本文地址:http://blog.csdn.net/scarthr/article/details/42524599
SurfaceView是一个可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。它的特性是:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView。
一 SurfaceView的使用
我们创建一个MyView继承SurfaceView,实现SurfaceHolder.Callback接口。
- package com.thr.testsurfaceview;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class MyView extends SurfaceView implements SurfaceHolder.Callback {
-
- public MyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- getHolder().addCallback(this);
- }
-
- public void draw() {
-
- Canvas canvas = getHolder().lockCanvas();
-
-
- getHolder().unlockCanvasAndPost(canvas);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
-
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
-
- draw();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
-
- }
- }
这个SurfaceHolder相当于Surface的一个控制器,用它来控制SurfaceView的大小,图形等等。
注意这个draw方法要在Surface创建后调用,在被销毁前结束。
二 使用SurfaceView绘制图形
我们在构造方法中设置好画笔的颜色,draw方法里画图就可以了:
- package com.thr.testsurfaceview;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class MyView extends SurfaceView implements SurfaceHolder.Callback {
-
- private Paint paint;
-
- public MyView(Context context, AttributeSet attrs) {
- super(context, attrs);
- paint = new Paint();
- paint.setColor(Color.RED);
- getHolder().addCallback(this);
- }
-
- public void draw() {
-
- Canvas canvas = getHolder().lockCanvas();
- canvas.drawColor(Color.WHITE);
- canvas.drawRect(0, 0, 100, 100, paint);
-
- getHolder().unlockCanvasAndPost(canvas);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
-
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
-
- draw();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
-
- }
- }
然后在Activity中setContentView时直接设置我们的MyView就可以看到效果了。
三 绘制组合图形
我们创建这样一个容器类:
- package com.thr.testsurfaceview;
-
- import java.util.ArrayList;
- import java.util.List;
-
- import android.graphics.Canvas;
-
- public class Container {
-
- private List<Container> children;
-
- public Container() {
- children = new ArrayList<Container>();
- }
-
- public void draw(Canvas canvas) {
- childrenDraw(canvas);
- for (Container c : children) {
- c.draw(canvas);
- }
- }
-
- public void childrenDraw(Canvas canvas) {
-
- };
-
- public void addChildrenView(Container child) {
- children.add(child);
- }
-
- public void removeChildrenView(Container child) {
- children.remove(child);
- }
- }
它有添加
和移除子控件的方法,draw方法是以此调用子控件的childrenDraw方法,如果还有子
控件,再调子控件的children方法。
在创建一个画圆和正方形的类,都继承自Container:
- package com.thr.testsurfaceview;
-
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
-
- public class Circle extends Container {
- private Paint paint;
-
- public Circle() {
- paint = new Paint();
- paint.setColor(Color.RED);
- }
-
- @Override
- public void childrenDraw(Canvas canvas) {
- canvas.drawCircle(50, 50, 50, paint);
- }
- }
- package com.thr.testsurfaceview;
-
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
-
- public class Rect extends Container {
-
- private Paint paint;
-
- public Rect() {
- paint = new Paint();
- paint.setColor(Color.BLUE);
- }
-
- @Override
- public void childrenDraw(Canvas canvas) {
- canvas.drawRect(0, 0, 100, 100, paint);
- }
- }
最后是GameView类,继承自SurfaceView:
- package com.thr.testsurfaceview;
-
- import android.content.Context;
- import android.graphics.Canvas;
- import android.util.AttributeSet;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
-
- public class GameView extends SurfaceView implements SurfaceHolder.Callback {
-
- private Container container;
- private Rect rect = new Rect();
- private Circle circle = new Circle();
-
- public GameView(Context context, AttributeSet attrs) {
- super(context, attrs);
- container = new Container();
- rect = new Rect();
- circle = new Circle();
- rect.addChildrenView(circle);
- container.addChildrenView(rect);
- getHolder().addCallback(this);
- }
-
- public void draw() {
- Canvas canvas = getHolder().lockCanvas();
- container.draw(canvas);
- getHolder().unlockCanvasAndPost(canvas);
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width,
- int height) {
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- draw();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- }
- }
用Container包含了一个矩形,矩形又包含了一个圆,运行效果:
接下来我们让这个创建的图形移动起来。
我们在Container中添加成员变量x、y,用来记录绘图坐标。
修改Container的draw方法:
- public void draw(Canvas canvas) {
-
- canvas.translate(getX(), getY());
- childrenDraw(canvas);
- for (Container c : children) {
- c.draw(canvas);
- }
-
- }
在Rect的childrenDraw方法中,对坐标进行改变:
- setX(getX() + 1);
- setY(getY() + 2);
在GameView中加入定时器,每隔100毫秒重新绘制一次图形,达到图形移动的效果。
- private TimerTask task;
- private Timer timer;
-
- public void startTimer() {
- timer = new Timer();
- task = new TimerTask() {
-
- @Override
- public void run() {
- draw();
- }
- };
- timer.schedule(task, 100, 100);
- }
-
- public void stopTimer() {
- if (timer != null) {
- timer.cancel();
- timer = null;
- }
-
- }
在创建SurfaceView的时候启动定时器,在销毁SurfaceView的时候取消定时器。
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- startTimer();
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- stopTimer();
- }
源码下载