Android 利用SurfaceView进行图形绘制
利用SurfaceView进行绘制
SurfaceView使用介绍
SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作。
要使用SurfaceView进行绘制,步骤如下:
1.用SurfaceView进行绘制,首先要创建一个类,继承 SurfaceView
,同时这个类应该实现SurfaceHolder.Callback接口。
这个接口中的三个回调函数(surfaceChanged(SurfaceHolder holder, int format, int width, int height),surfaceCreated(SurfaceHolder holder),surfaceDestroyed(SurfaceHolder holder))分别对应Surface何时更改、创建和销毁。
2.对Surface对象的操作是通过SurfaceHolder来进行的。所以,在你的SurfaceView类初始化的时候,你需要调用 getHolder()
来获得SurfaceHolder对象,然后用addCallback()加上回调接口(因为你的类实现了相应的接口,所以此处传入this即可)。
3.在你的SurfaceView类中应该建立一个线程类,处理绘制操作。为此,要向这个线程类传递上面获得的SurfaceHolder对象。
4.绘制:在线程类的run()方法中进行绘制操作,通过lockCanvas()
方法获得Canvas对象,然后就可以用这个对象进行绘制,绘制完成后调用unlockCanvasAndPost(),传入Canvas对象,这时Surface将会按Canvas进行绘制。
注意:每次利用SurfaceHolder获得画布时,前一次的内容将会保留。
代码示例

package com.example.hellosurfaceview; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private DrawThread mThread = null; public MySurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MySurfaceView(Context context) { super(context); init(); } private void init() { Log.d(AppConstants.LOG_TAG, "init"); SurfaceHolder holder = getHolder(); holder.addCallback(this); mThread = new DrawThread(holder); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { Log.d(AppConstants.LOG_TAG, "onSizeChanged"); super.onSizeChanged(w, h, oldw, oldh); } @Override public void surfaceCreated(SurfaceHolder holder) { Log.d(AppConstants.LOG_TAG, "surfaceCreated"); mThread.setRun(true); mThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Log.d(AppConstants.LOG_TAG, "surfaceChanged"); } @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.d(AppConstants.LOG_TAG, "surfaceDestroyed"); mThread.setRun(false); } /** * 绘制线程类 * */ public class DrawThread extends Thread { private SurfaceHolder mHolder = null; private boolean isRun = false; public DrawThread(SurfaceHolder holder) { Log.d(AppConstants.LOG_TAG, "DrawThread Constructor"); mHolder = holder; } public void setRun(boolean isRun) { Log.d(AppConstants.LOG_TAG, "DrawThread setRun: " + isRun); this.isRun = isRun; } @Override public void run() { Log.d(AppConstants.LOG_TAG, "DrawThread run"); int count = 0; while (isRun) { Canvas canvas = null; synchronized (mHolder) { try { Log.d(AppConstants.LOG_TAG, "Drawing-------------"); canvas = mHolder.lockCanvas(); canvas.drawColor(Color.WHITE); Paint p = new Paint(); p.setColor(Color.BLACK); Rect r = new Rect(100, 50, 300, 250); canvas.drawRect(r, p); canvas.drawText("这是第" + (count++) + "秒", 100, 310, p); Thread.sleep(1000);// 睡眠时间为1秒 } catch (Exception e) { Log.d(AppConstants.LOG_TAG, "throw Exception in run"); e.printStackTrace(); } finally { if (null != canvas) { mHolder.unlockCanvasAndPost(canvas); } } } } } } }
参考资料
官方文档:
API Guides:Canvas and Drawables
http://developer.android.com/guide/topics/graphics/2d-graphics.html
SurfaceView:
http://developer.android.com/reference/android/view/SurfaceView.html
SurfaceHolder:
http://developer.android.com/reference/android/view/SurfaceHolder.html
博客:
Android之SurfaceView学习(一):
http://www.cnblogs.com/xuling/archive/2011/06/06/android.html
剖析 SurfaceView:
http://blog.csdn.net/xiaominghimi/article/details/6090575
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了