SurfaceView使用介绍
2016-01-07 16:54
239 查看
转载请注明:http://blog.csdn.net/zhangshuaizaxia/article/details/50476869,来自Davencheung的博客!
下面是surfaceView的API的译文(摘自网络)
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置,surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者
surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和
surfaceDestroyed(SurfaceHolder)。
surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:
1. 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
2. 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。
另外,通过下面几点,你可以确定何时选择使用SurfaceView:
1. View适用于主动更新的情况下,而SurfaceView适应于被动刷新,频繁的刷新,例如游戏界面;
2. View在主线程中对画面进行刷新,而SurfaceView通常会通过一个子线程来进行页面的刷新;(可以在子线程中做大量的处理)
3. View在绘图的时候没有使用双缓存的机制,而SurfaceView在底层使用双缓存的机制。
基本上按照上面的使用方法,就可以完成很多事情。我们要做的就是在下面这行代码下面添加一些自己的内容即可!
而在MainActiivity中只需要如下的处理:
例如,修改下面的代码,就可以让界面每5秒刷新一次!
记住,这个sleep需要在while循环调用,因为,第一次运行之后,界面就一直通过这个循环来刷新,不会再走其他的流程,代码无法执行到(Android群英会中的示例应该有问题),直到退出应用!
运行的效果图如下:
什么是SurfaceView?
其实在去年学习Android的APIDEMO的时候,有接触到SurfaceView, 但是却一直不是很明白他的作用,只知道他和View有一些区别。事实上,SurfaceView是继承View。我们知道Android系统通过发出VSYNC信号来刷新屏幕,刷新的时间间隔为16ms,也就是在有屏幕刷新的情况下,view的draw函数中的内容必须在16ms内完成,如果超出这个时间,就会出现掉帧。而SurfaceView何时刷新,则是可以控制的。下面是surfaceView的API的译文(摘自网络)
SurfaceView是视图(View)的继承类,这个视图里内嵌了一个专门用于绘制的Surface。你可以控制这个Surface的格式和尺寸。Surfaceview控制这个Surface的绘制位置,surface是纵深排序(Z-ordered)的,这表明它总在自己所在窗口的后面。surfaceview提供了一个可见区域,只有在这个可见区域内 的surface部分内容才可见,可见区域外的部分不可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者
surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面 有透明控件,那么它的每次变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。你可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口。surfaceview变得可见时,surface被创建;surfaceview隐藏前,surface被销毁。这样能节省资源。如果你要查看 surface被创建和销毁的时机,可以重载surfaceCreated(SurfaceHolder)和
surfaceDestroyed(SurfaceHolder)。
surfaceview的核心在于提供了两个线程:UI线程和渲染线程。这里应注意:
1. 所有SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序主线程。渲染线程所要访问的各种变量应该作同步处理。
2. 由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHolder.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效的surface。
另外,通过下面几点,你可以确定何时选择使用SurfaceView:
1. View适用于主动更新的情况下,而SurfaceView适应于被动刷新,频繁的刷新,例如游戏界面;
2. View在主线程中对画面进行刷新,而SurfaceView通常会通过一个子线程来进行页面的刷新;(可以在子线程中做大量的处理)
3. View在绘图的时候没有使用双缓存的机制,而SurfaceView在底层使用双缓存的机制。
SurfaceView使用模板
SurfaceView的使用是有规矩可以遵循,在《Android群英会》一书中,作者给出了一个使用模板,使用起来很简单!package com.cheungshuai.surfaceview; import java.util.Calendar; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Path; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; /** * * @author davencheung * */ public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback, Runnable{ private SurfaceHolder mHolder; private Canvas mCanvas; private boolean mIsDrawing;//whether is drawing public SurfaceViewTemplate(Context context) { super(context); initView(); } public SurfaceViewTemplate(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } private void initView(){ mHolder = getHolder(); mHolder.addCallback(this); setFocusable(true); setFocusableInTouchMode(true); setKeepScreenOn(true); //do something here! mPaint = new Paint(); mPaint.setTextSize(50); mPaint.setColor(Color.RED); mPaint.setTextAlign(Align.CENTER); } private Calendar mCalendar; private Paint mPaint; private String mTime; @Override public void run() { while(mIsDrawing){ draw(); } } private void draw(){ try{ mCanvas = mHolder.lockCanvas(); //do something here! mCanvas.drawColor(Color.WHITE); mCalendar = Calendar.getInstance(); mTime = mCalendar.get(Calendar.HOUR_OF_DAY)+"时"+ mCalendar.get(Calendar.MINUTE)+"分"+ mCalendar.get(Calendar.SECOND)+"秒"; mCanvas.drawText(mTime, getWidth()/2, getHeight()/2, mPaint); }catch(Exception e){ }finally{ if(mCanvas != null){ mHolder.unlockCanvasAndPost(mCanvas); } } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { mIsDrawing = true; new Thread(this).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { mIsDrawing = false; } }
基本上按照上面的使用方法,就可以完成很多事情。我们要做的就是在下面这行代码下面添加一些自己的内容即可!
//do something here!
而在MainActiivity中只需要如下的处理:
SurfaceViewTemplate sv = new SurfaceViewTemplate(this); setContentView(sv);
控制刷新间隔时间
另外,我们可以在线程的run函数中控制线程的运行,然后是的刷新间隔时间改变。例如,修改下面的代码,就可以让界面每5秒刷新一次!
while(mIsDrawing){ draw(); try{ Thread.sleep(5000); } catch (InterruptedException e){ e.printStackTrace(); } }
记住,这个sleep需要在while循环调用,因为,第一次运行之后,界面就一直通过这个循环来刷新,不会再走其他的流程,代码无法执行到(Android群英会中的示例应该有问题),直到退出应用!
运行的效果图如下:
相关文章推荐
- SQL语句构建器类
- 求飘过各种科目
- redis重启失败
- 密码加密
- cocos2d-x Undefined symbols for architecture x86_64 when porting iOS app in Xcode? 问题的解决
- 升级github的版本库号
- XML知识点概念小摘
- android连点两次返回键退出程序
- spring-boot结合logback日志框架
- 软件测试 (二) 界面测试
- w3techs web站点使用技术调查
- JSON.stringify()与JSON.parse()
- [React Testing] Children with Shallow Rendering
- 贪吃蛇改进版
- jquery操作select(设置选中值,取选中值)
- 序列号的设计,不重复的实现一机一码
- hibernate中 org.hibernate.MappingException
- IDA Pro的使用(1)反汇编
- java—(6)native strictfp transient throw throws synchronized volatile关键字
- java内存溢出分析(二)