Android基于view视图进行拓展的视图类SurfaceView详解

  次阅读 来源:互联网(转载协议) 2015-10-13 07:38 我要评论(0)

,这个视图里内嵌了一个专门用于绘制的Surface。可以控制这个Surface的格式和尺寸。SurfaceView控制这个Surface的绘制位置

SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类上使用双缓冲机制,在新的线程中更新画面所以新界面速度比view快。

Surface是纵深排序的,这说明它总在自己所在的窗口的后面。SurfaceView 提供了一个可见区域,只有在这个可见区域内的surface部分内容才可见,可见区域外部部分不可 见。surface的排版显示受到视图层级关系的影响,它的兄弟节点会在顶端显示。这意味者surface的内容会被它的兄弟视图遮挡,这一特性可以用来 放置遮盖物(overlays)(例如:文本和按钮等控件)。但是,当surface上面有透明控件时,它的每次变化都会引起框架重新计算它和顶层控件的 透明效果,这会影响性能。可以通过SurfaceHolder接口访问这个surface,getHolder()方法可以得到这个接口

Surfaceview变的可见时,surface被创建,surfaceView隐藏前,surface被毁灭。这样可以节省资源。 surface创建:surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder).

SurfaceView的核心提供了两个线程:UI线程和渲染线程。应该注意的是:

a.所有的SurfaceView和SurfaceHolder.Callback的方法都应该在UI线程里调用,一般来说就是应用程序的主线程。渲染线程所要访问的各种变量应该做同步处理。

b.由于surface可能被销毁,它只在SurfaceHolder.Callback.surfaceCreated()和 SurfaceHoledr.Callback.surfaceDestroyed()之间有效,所以要确保渲染线程访问的是合法有效地surface.

二、SurfaceView类 和View类的区别

SurfaceView 和View的最本质的区别在于,surfaceView是在一个在新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在 UI的主线程中更新画面,可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞,那么将无法响应按键,触摸等消息。当使 用surfaceView由于是在新的线程中更新画面所以不会阻塞你的UI主线程,但是这也会有另外一个问题,就是事件同步。比如你触屏了一下,你需要 surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这样就会有点复杂了。

View:必须在UI的主线程中更新画面,用于被动更新画面。

surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。

所以在游戏的应用上,根据游戏的特点,一般分为两类:

a. 被动更新画面的。比如棋类,这种用view就好。因为画面的跟新依赖于onTouch来更新,可以直接使用invalidate.因为这种情况下,这一次Touch和下一次Touch需要的时间比较长些,不会产生

影响。

b.主动更新:比如一个人在一直跑动。这就需要一个单独的thread不停地重绘人的转台,避免阻塞mian UI Thread 。所以显然view 不适合,需要surfaceView来控制。

(1.)定义:

可以直接从内存或者DMA等硬件接口取得图像数据,是个非常重要的绘图容器。

它的特性:可以在主线程之外的线程中向屏幕绘图上。这样可以避免画图任务繁重时造成主线程阻塞,从而提高了程序的反应速度。在游戏开发中多用到SurfaceView,游戏中的背景、人物、动画等等尽量在画布canvas中画出。

SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用窗体不见 的应用使用的。Android系统中一个重要的概念和线索是Surface.View及其子类(TextView,Button等)要画在Surface 上。每个Surface创建一个Canvas对象(但属性时常改变),用来管理view在Surface上的绘图操作,如画点画线,使用它是,一般都是出 现在

最顶层。

(2.)实现

首先继承SurfaceView并实现SurfaceHolder.Callback接口

使用接口的原因:因为使用SurfaceView有一个原则,所有的绘图工作必须得在Surface被创建之后才能开始(Surface可以当作显 存的一个映射,写入到Surface的内容,可以被直接复制到显存中从而显示出来,这使得显示的速度会非常快),而在Surface被销毁之前必须结束。 所以CallBack中的surfaceCreated和surfaceDestroyed就成了绘图代理代码的边界。

需要重写的方法:

a. public void sufaceChanged(SurfaceHolder holder,int format,int width,int height){}//Surface的大小发生改变时调用

b. public void surfaceCreated(SurfaceHolder holder){}//Surface创建时激发,一般在这里调用画面的线程。

c. public void surfaceDestroyed(SurfaceHolder holder){}//销毁时激发,一般在这里将画面的线程停止、释放。

d. public void addCallback{};//给SurfaceView添加一个回调函数。

e. public void lockCanvas{};//锁定画布。绘图之前必须锁定画布才能够得到画布对象。

f. public void unlockCanvasAndPost{};//开始绘制时锁定了画布,绘制完成后解锁画布。

g. public void removeCallback:从SurfaceView中移除回调函数。

SurfaceView不同View之处在于,SurfaceView不需要通过线程来更新视图,但是再绘制前需要使用locakCanvas锁定 画布,并且得到画布,然后再画布上绘制你需要的图像。绘制完成后需要使用lockCanvasAndPost方法来解锁画布。于是才能显示在屏幕上。事件 的处理规则和View是一样的。

本站部分文章来源于网络以及网友投稿,本站只负责对文章进行整理、排版、编辑,是出于传递更多信息之目的,并不意味着赞同其观点或证实其内容的真实性。如果您有什么意见或建议,请联系QQ28-1688-302!

人工智能实验室
相关文章相关文章
  • Oculus公布原型机,大幅度提升可视角,能实现140°的视场水平

    Oculus公布原型机,大幅度提升可视角,能实现140°的视场水平

  • teamLab创始人猪子寿之: 抛去衣食住行,我还剩下什么?

    teamLab创始人猪子寿之: 抛去衣食住行,我还剩下什么?

  • 2018深圳国际人工智能展览会 2018 shenzhen International Artif

    2018深圳国际人工智能展览会 2018 shenzhen International Artif

  • Michael I. Jordan带你解读百万奖金ATEC蚂蚁人工智能大赛

    Michael I. Jordan带你解读百万奖金ATEC蚂蚁人工智能大赛

网友点评网友点评
阅读推荐阅读推荐

据外媒报道,STEER打造了首款完全自动驾驶停车技术,旨在使常规车辆转变为无人驾驶车辆。STEER的首款技术应用是4级自动驾驶及网络安全停车...

近日,美国软性机器抓手制造商 Soft Robotics 宣布,获得 2000 万美元的融资,本轮投资者包括 Scale Venture Partners,Calibrate Ventures...

据外媒报道,加州车管局发布了《2017自动驾驶脱离报告(California Autonomous Vehicle Disengagement Reports)》,其中谈及了脱离的具体...

用人机语音交互,来解决智能家居适老的问题;通过家庭门禁与安防套件、空气净化套件、可燃气体与有害气体监控套件等相互联动,在不同生活情...