android的图像图像绘图surfacev

上传人:tian****1990 文档编号:72695707 上传时间:2019-01-23 格式:PPT 页数:18 大小:1.15MB
返回 下载 相关 举报
android的图像图像绘图surfacev_第1页
第1页 / 共18页
android的图像图像绘图surfacev_第2页
第2页 / 共18页
android的图像图像绘图surfacev_第3页
第3页 / 共18页
android的图像图像绘图surfacev_第4页
第4页 / 共18页
android的图像图像绘图surfacev_第5页
第5页 / 共18页
点击查看更多>>
资源描述

《android的图像图像绘图surfacev》由会员分享,可在线阅读,更多相关《android的图像图像绘图surfacev(18页珍藏版)》请在金锄头文库上搜索。

1、android的图像图像-SurfaceView类,2019/1/23,View和SurfaceView,View类是android的一个超类,每一个View都有一个用于绘画的画布,这个画布可以进行任意的扩展。有的时候我们需要自定义VIew实现自己想要的视图。view、SurfaceView是游戏开发中经常用到的视图。 View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢。 SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快

2、。,View的缺陷,View缺乏双缓冲机制 当程序需要更新View上的图像时,必须重绘View上显示的整张图片。,SurfaceView 类,SurfaceView是从View基类中派生出来的显示类,直接子类有GLSurfaceView和VideoView,GL和视频播放以及Camera摄像头一般均使用SurfaceView. SurfaceView可以控制表面的格式,比如大小、显示在屏幕中的位置,最关键是的提供了SurfaceHolder类,使用getHolder方法获取,相关的方法有 lockCanvas()、 lockCanvas(Rect dirty) 、 removeCallback

3、(Callback callback)、 unlockCanvasAndPost(Canvas canvas) 控制图形以及绘制。 对于Surface,Android底层还提供了GPU加速功能,所以一般实时性很强的应用中主要使用SurfaceView而不是直接从View 构建,同时Android后面用到的OpenGL中的GLSurfaceView也是从该类实现。,2019/1/23,callback接口,只要继承SurfaceView类并实现SurfaceHolder.Callback接口就可以实现一个自定义的SurfaceView,SurfaceHolder.Callback在底层的Surf

4、ace状态发生变化的时候通知View,SurfaceHolder.Callback具有如下的接口: surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不要在这个函数中绘制Surface。 surfaceChanged(SurfaceHolder holder, int format, int width,int height):当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至

5、少会被调用一次。,注意:一个SurfaceView只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed()调用之间是可用的,其他时间是得不到 它的Canvas对象的(null)。,Android-surfaceView 与View 的区别,SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面,而View必须在UI的主线程中更新画面。那么在UI的主线程中更新画面 可能会引发问题,比如更新画面的时间过长,那么主UI线程会被正在

6、绘制的函数阻塞。那么将无法响应按键、触屏等消息。使用surfaceView ,由于是在新的线程中更新画面所以不会阻塞UI主线程。但这也带来了另外一个问题,就是事件同步。比如触屏了一下,需要surfaceView中 thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。所以基于以上,根据游戏特点,一般分成两类: (1 )被动更新画面的。比如棋类,这种用view就好了。因为画面的更新是依赖于 onTouch 来更新,可以直接使用 invalidate。 因为这种情况下,这一次Touch和下一次的Touch需要的时间比较长些

7、,不会产生影响。 (2 )主动更新。比如一个人在一直跑动。这就需要一个单独的thread不停的重绘人的状态,避免阻塞主线程。所以显然view不合适,需要surfaceView来控制。,使用SurfaceView绘制矩形,2019/1/23,public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(new MyView(this); ,class MyView extends SurfaceView implements SurfaceHolder.Call

8、back SurfaceHolder holder; public MyView(Context context) super(context); holder=getHolder(); holder.addCallback(this); ,public void surfaceCreated(SurfaceHolder holder) new Thread(new MyThread().start(); ,使用SurfaceView绘制矩形,2019/1/23,class MyThread implements Runnable public void run() /锁定画布,通过其返回的画

9、布对象canvas,在其上面画图 Canvas canvas=holder.lockCanvas(); canvas.drawColor(Color.WHITE); Paint paint=new Paint(); paint.setColor(Color.YELLOW); canvas.drawRect(10, 10, 220, 180, paint); holder.unlockCanvasAndPost(canvas);/结束锁定画图,并提交编辑 ,SurfaceView绘图机制,重写CallBack对象的surfaceCreate方法,在该方法中为SurfaceView绘制背景,并避免

10、背景图片被下一次lockCanvas遮挡。 监听触摸事件,每次触摸屏幕时,程序会锁定触碰周围的区域,那么就只更新该区域的数据,而且本次的lockCanvas会遮挡上一次的lockCanvas后绘制的图形。 注:第一次绘制的图形可能会被第二次的lockCanvas遮挡,第三次的lockcanvas又可能遮挡第二次lockCanvas的区域,但不可能遮挡第一次的lockCanvas区域,SurfaceView绘图机制,2019/1/23,holder.addCallback(new Callback() public void surfaceDestroyed(SurfaceHolder hold

11、er) public void surfaceCreated(SurfaceHolder holder) Canvas canvas=holder.lockCanvas(); Bitmap bitmap=BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.sun); canvas.drawBitmap(bitmap, 0, 0, null); holder.unlockCanvasAndPost(canvas); holder.lockCanvas(new Rect(0,0,0,0); holder

12、.unlockCanvasAndPost(canvas); public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) );,SurfaceView绘图机制,2019/1/23,sf.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) if(event.getAction()=MotionEvent.ACTION_DOWN) int cx=(int) even

13、t.getX(); int cy=(int) event.getY(); Canvas canvas=holder.lockCanvas(new Rect(cx-50,cy-50,cx+50,cy+50); canvas.save(); canvas.rotate(30, cx, cy); paint.setColor(Color.YELLOW); canvas.drawRect(cx-40, cy-40, cx, cy, paint); canvas.restore(); paint.setColor(Color.GREEN); canvas.drawRect(cx, cy, cx+40,

14、cy+40, paint); holder.unlockCanvasAndPost(canvas); return false; );,SurfaceView的双缓冲使用,2019/1/23,前面简单介绍了SurfaceView的使用,这次就介绍SurfaceView的双缓冲使用。双缓冲是为了防止动画闪烁而实现的一种多线程应用,基于SurfaceView的双缓冲实现很简单,开一条线程并在其中绘图即可。 程序运行截图如下,左边是开单个线程读取并绘图,右边是开两个线程,一个专门读取图片,另一个专门绘图:,对比一下,右边动画的帧速明显比左边的快,左右两者都没使用Thread.sleep()。因为Su

15、rfaceView每次绘图都会锁定Canvas,也就是说同一片区域这次没画完下次就不能画,因此要提高双缓冲的效率,就得开一条线程专门画图,开另外一条线程做预处理的工作。,SurfaceView的双缓冲使用,Button btn1, btn2; SurfaceView sfv; SurfaceHolder sfh; ArrayList imglist = new ArrayList(); int imgwidth, imgheight; Bitmap bitmap; public void onCreate(Bundle savedInstanceState) super.onCreate(sa

16、vedInstanceState); setContentView(R.layout.main); btn1 = (Button) this.findViewById(R.id.btn1); btn2 = (Button) this.findViewById(R.id.btn2); btn1.setOnClickListener(new MyListener(); btn2.setOnClickListener(new MyListener(); sfv = (SurfaceView) this.findViewById(R.id.SurfaceView01); sfh = sfv.getHolder(); sfh.addCallback(new MyCallBack();/ 自动运行surfaceCreated ,SurfaceView的双缓冲使用,class MyListener implements View.OnClickListener public v

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号