SurfaceView和View绘图的区别
- View适用于主动更新的情况下,而SurfaceView适用于被动的更新,比如频繁的刷新.
- View在主线程中对画面进行刷新,SurfaceView通过一个子线程对页面进行抓心
- View在绘图时没有使用双缓冲机制,SurfaceView在底层机制中实现了双缓冲机制.
总结:如果自定义View需要频繁的刷新,或者刷新的数据量比较大的时候就要使用SurfaceView了
SurfaceView模板
public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback ,Runnable {
//SurfaceHolder
private SurfaceHolder mHolder;
//用于绘图的Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;
/**
* 三个构造方法
*/
public SurfaceViewTemplate(Context context) {
super(context);
init();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//初始化
private void init() {
mHolder=getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
//mHolder.setFormat(PixelFormat.OPAQUE);
}
//SurfaceView的创建
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing=true;
new Thread(this).start();
}
//SurfaceView的改变
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
//SurfaceView的销毁
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing=false;
}
@Override
public void run() {
while (mIsDrawing){
draw();
}
}
private void draw() {
try {
//可以获得当前Canvas绘制的对象
mCanvas=mHolder.lockCanvas();
//绘制的东西在这里写入
}catch (Exception e){
}finally {
if (mCanvas!=null){
//提交
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
}
屏幕绘制一个正弦函数
public class Sin extends SurfaceView implements SurfaceHolder.Callback ,Runnable {
//SurfaceHolder
private SurfaceHolder mHolder;
//用于绘图的Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;
private int x,y=0;
private Paint mPaint;
private Path mPath;
/**
* 三个构造方法
*/
public Sin(Context context) {
super(context);
init();
}
public Sin(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Sin(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//初始化
private void init() {
mHolder=getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(10);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeJoin(Paint.Join.ROUND);
}
//SurfaceView的创建
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing=true;
mPath.moveTo(0, 400);
new Thread(this).start();
}
//SurfaceView的改变
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
//SurfaceView的销毁
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing=false;
}
@Override
public void run() {
while (mIsDrawing){
draw();
x+=1;
y= (int) (100*Math.sin(x*2*Math.PI/180)+400);
mPath.lineTo(x, y);
}
}
private void draw() {
try {
//可以获得当前Canvas绘制的对象
mCanvas=mHolder.lockCanvas();
//SurfaceView背景
mCanvas.drawColor(Color.YELLOW);
mCanvas.drawPath(mPath,mPaint);
}catch (Exception e){
}finally {
if (mCanvas!=null){
//提交
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
}
在屏幕上绘制图形
public class Art extends SurfaceView implements SurfaceHolder.Callback ,Runnable {
//SurfaceHolder
private SurfaceHolder mHolder;
//用于绘图的Canvas
private Canvas mCanvas;
//子线程标志位
private boolean mIsDrawing;
private Path mPath;
private Paint mPaint;
/**
* 三个构造方法
*/
public Art(Context context) {
super(context);
init();
}
public Art(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public Art(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
//初始化
private void init() {
mHolder=getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
this.setKeepScreenOn(true);
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(10);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeJoin(Paint.Join.ROUND);
}
//SurfaceView的创建
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing=true;
new Thread(this).start();
}
//SurfaceView的改变
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
//SurfaceView的销毁
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing=false;
}
@Override
public void run() {
long start=System.currentTimeMillis();
while (mIsDrawing){
draw();
}
long end=System.currentTimeMillis();
//50-100之间
if (end-start<100){
try {
Thread.sleep(100-(end-start));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void draw() {
try {
//可以获得当前Canvas绘制的对象
mCanvas=mHolder.lockCanvas();
mCanvas.drawColor(Color.WHITE);
mCanvas.drawPath(mPath,mPaint);
//绘制的东西在这里写入
}catch (Exception e){
}finally {
if (mCanvas!=null){
//提交
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int x= (int) event.getX();
int y= (int) event.getY();
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mPath.moveTo(x,y);
break;
case MotionEvent.ACTION_MOVE:
mPath.lineTo(x,y);
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
}