Android SurfaceView学习
来源:互联网 发布:443端口是什么服务 编辑:程序博客网 时间:2024/06/16 12:50
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 学习笔记
- android 之surfaceView 学习
- Android SurfaceView学习示例
- Android之SurfaceView学习
- Android之SurfaceView学习
- Android之SurfaceView学习
- Android之SurfaceView学习
- Android中SurfaceView学习
- Android之SurfaceView学习
- Android之SurfaceView学习
- Android SurfaceView 学习
- Android之SurfaceView学习
- Android之SurfaceView学习
- Android:SurfaceView学习
- Android SurfaceView学习示例
- Android之SurfaceView学习
- Android SurfaceView学习示例
- Android之SurfaceView学习
- Xutils3的使用
- Unicode、UTF-8 和 ISO8859-1 区别
- UE4下实现Vive手柄拾取物品
- Java NIO
- PHP下C扩展开发
- Android SurfaceView学习
- 3013
- Android ANR发生原因总结(来自本人cnblogs博客)
- Hibernate 中 的 SessionFactory 接口
- 重复new对象所带来的问题和解决办法
- 练习三 1012
- 这几年工作的总结
- scala简介
- Realm的翻译