您的位置:首页 > 移动开发 > Android开发

Android SurfaceView学习

2016-05-29 10:07 537 查看
1.这几天学习了徐老师讲的SurfaceView,说实在的讲的不是很清楚,后经我查找资料,弄明白了一些,因此来做一个笔记记录下。

2.首先我们先说一下surfaceholder,surface,surfaceview的关系。

surfaceview:是继承view,本质上是一个view,与view最大的不同就是,surfaceview可以在非主线程中通过canves来绘制图像,在一些比较繁琐的绘图过程中,继承传统的view,完成不了往往出现卡顿的情况,因为传统的view执行ondraw方法都是在主线程中进行的,当ondraw耗时久的话,就会卡顿。但是surfaceview不同 他支持非主线程操作canves画布。

surfaceholder:官网给出来的解释是:surfaceholder是一个接口,可以通过这个接口设置surface的大小,格式,并且检测surface的变化。

surface:首先要知道surface是在surfaceview的内部。通俗的来讲就是展示图行的那部分。

3.下面我们就来使用surfaceview 来绘制一个正玄函数的图行。通过继承SurfaceView类,并且实现Surfaceholder.callback接口,和Runable接口。具体代码如下:

public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{
private SurfaceHolder holder;
private Canvas canvas;
private boolean misdrawing;
Path path;
private Surface sf;
public MySurfaceView(Context context) {
super(context);
init();
}

public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

public void init()
{
holder=getHolder();
sf=holder.getSurface();
holder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(false);
this.setKeepScreenOn(true);
holder.setFormat(PixelFormat.OPAQUE);
path=new Path();
path.moveTo(0,250);
for (int i=10;i<800;i++)
{
int y=(int)(100*Math.sin(i*2*Math.PI/180)+400);
path.lineTo(i,y);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
misdrawing=true;
new Thread(this).start();
Toast.makeText(getContext(), "create", Toast.LENGTH_SHORT).show();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Toast.makeText(getContext(), "change", Toast.LENGTH_SHORT).show();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

misdrawing=false;
Toast.makeText(getContext(), "Destroy", Toast.LENGTH_SHORT).show();
}

@Override
public void run() {
draw();
}

public void draw()
{
Paint p=new Paint();
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(5);
try {
synchronized(holder) {
canvas = holder.lockCanvas();
canvas.drawColor(Color.WHITE);
canvas.drawPath(path,p);

// canvas.drawCircle(getMeasuredWidth() / 2, getMeasuredHeight() / 2, 80, p);
}
}
catch (Exception e)
{

e.printStackTrace();
}
finally {
holder.unlockCanvasAndPost(canvas);
}
}
}


重写的这部分代码:
@Override
public void surfaceCreated(SurfaceHolder holder) {
misdrawing=true;
new Thread(this).start();
Toast.makeText(getContext(), "create", Toast.LENGTH_SHORT).show();
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Toast.makeText(getContext(), "change", Toast.LENGTH_SHORT).show();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {

misdrawing=false;
Toast.makeText(getContext(), "Destroy", Toast.LENGTH_SHORT).show();
}


是Surfaceholder.callback接口提供的,从名字上就可以看出是对Surface对象的各种监听。init()方法主要是初始化一些数据。
具体步骤可以总结为这几步:

1.得到Surfaceholder接口,通过调用getHolder()方法。

2.为surfaceholder添加CallBack监听。

其中setFormat可以设置surface的格式。这就验证了前面对Surfaceholder的解释,SurfaceView主要针对surface对象的,可以对surface对象的大小,格式,以及监听surface的变化。

在上面的代码中,我申明了一个surface对象。因为在查看api的时候发现Surfaceholder接口提供了一个getSurface方法,然后再通过查看api,看下surface类有哪些方法。api截图如下:



其中做标记的方法,是我们后面需要的。并且这些方法在SurfaceHolder


接口中也提供。这是不是很奇怪。既然都提供 为什么百度搜索到的资源都是有surfaceholer来获取到canves,而很少通过surface来获取canves。

lockCanvas(),方法获取一块画布,因为可以在子线程中对surfaceview的canvas进行操作,因而可能出现这种情况,3,4子线程同时方法canvas,因此在lockCanvas()中,api已经帮我加上锁了,所以导致后面canvas绘制完毕后,需要及时“解锁”,那么canvas 才能被下一个线程使用。

这里需要注意一点的就是:SurfaceView 默认貌似是黑色的,因为博主在写demo的时候刚开始发现SurfaceView展现出来是黑色的,因此在canvas里面加了drawcolor。代码部分是用Surfaceholder来获取canvas的。当然我们也可以通过surface对象来获取,不过在执行lockcanvas()方法时候,要加一个参数Rect对象,这个对象就是指明surface的大小的。当然SurfaceHolder
也提供了这个方法,来设置surface的大小。

具体代码,大家动手敲敲写写就会明白是怎么一回事了。

总结:自定义SurfaceView套路

1.继承SurfaceView类,实现SurfaceHolder.Callback接口,和Runable接口

2.init()初始化一些参数。

3.写一个draw方法,用来绘制图像。

4.当surface执行Destroyed方法的时候,我们终止子线程的运行。

今天就写到这,这只是对SurfaceView的初步了解,后面有机会的话到时候在写下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android SurfaceView