Android自定义控件开发入门与实战(15)SurfaceView,看完就能找到工作_安卓开发surfaceview设置停止刷新-程序员宅基地

技术标签: 程序员  面试  android  移动开发  

SurfaceHolder surfaceHolder = getHolder();

Canvas canvas1 = surfaceHolder.lockCanvas();

//绘图操作

surfaceHolder.unlockCanvasAndPost(canvas1);

我们先通过surfaceHolder.lockCanvas()函数得到SurfaceView的自带缓冲画布,并将这个画布加锁,防止它被别的线程更改。

当绘制完后,我们通过surfaceHolder.unlockCanvasAndPost(canvas)来将缓冲画布释放,并将所画的内容更新到主线程的画布上,显示的显示在屏幕上。

Q:为什么得到画布时要加锁?

A:SurfaceView的缓冲画布时可以在线程中更新的,这是它的一大特点,而如果我们有多个线程同时更新画布,那么这个画布岂不是被画的乱七八糟?所以我们需要加锁。

而加锁会产生另一个问题,当画布被其他线程锁定的时候或者缓存的Canvas没有被创建的时候,surfaceHolder.lockCanvas()一定会返回null,如果继续使用canvas,必须要做判空处理,也需要在画布为空的时候添加重试策略。

学到这些,我们更改之前的捕捉手势的代码:

@Override

public boolean onTouchEvent(MotionEvent event) {

。。。

else if (event.getAction() == MotionEvent.ACTION_MOVE) {

mPath.lineTo(x, y);

}

drawCanvas();

return super.onTouchEvent(event);

}

private void drawCanvas() {

SurfaceHolder surfaceHolder = getHolder();

Canvas canvas = surfaceHolder.lockCanvas();

canvas.drawPath(mPa

《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享

th, mPaint);

surfaceHolder.unlockCanvasAndPost(canvas);

}

我们把postInvalidate()去掉,改成用缓冲画布来绘图,发现屏幕也变白了。

那其实,onTouchEvent方法是执行在主线程中的,所以在onTouchEvent中绘图跟直接重写View的onDraw()函数也没有什么区别了,那我们为什么还要用SurfaceView呢 = =!

其实SurfaceView的正确用法是在子线程中更新画布,我们在上述的代码中修改:

private void drawCanvas() {

new Thread(new Runnable() {

@Override

public void run() {

SurfaceHolder surfaceHolder = getHolder();

Canvas canvas = surfaceHolder.lockCanvas();

canvas.drawPath(mPath, mPaint);

surfaceHolder.unlockCanvasAndPost(canvas);

}

}).start();

}

3、监听Surface生命周期

上面我们简单的介绍了如何使用SurfaceView缓冲画布,其实与SurfaceView相关的有三个概念:Surface、SurfaceView、SurfaceHolder。

其实,这三个概念是典型的MVC模式。M是数据模型,在这里是Surface,Surface中保存着缓冲画布与绘图内容相关的各种信息,View即视图,代表用户交互界面,在这里就是SurfaceView,负责将Surface中存储的数据展示在View上。SurfaceHolder就是C,用它来操控Surface的数据。

既然我们知道SurfaceView的缓存Canvas是保存在Surface中的,那么,必然需要Surface存在的时候,才能够操作缓存Canvas,否则很容易获取到的Canvas是空的。

所以Android提供了SurfaceView的生命周期:

SurfaceHolder surfaceHolder = getHolder();

surfaceHolder.addCallback(new SurfaceHolder.Callback() {

@Override

public void surfaceCreated(SurfaceHolder holder) {

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override

public void sur

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_65145685/article/details/122142366

智能推荐

Layui实现点击文字、缩略图查看图片功能_layui查看图片-程序员宅基地

文章浏览阅读4.3k次。刚完成一个客户需求,同一个页面上要有点击缩略图查看大图功能,也有点击图片名称查看原图的功能。点击缩略图查看大图的功能点击缩略图查看大图的功能实现用的是layui开发文档内的layer.photos-相册层。官方开发文档里photos支持传入json和直接读取页面图片两种方式。下面是官方开发文档的截图,官方开发文档链接:https://www.layui.com/doc/m..._layui查看图片

ueditor的配置和使用-程序员宅基地

文章浏览阅读89次。ueditor下载好之后直接复制到项目的WebContent目录下,并将ueditor\jsp\lib下的jar包复制或者剪切到项目的lib目录下。先看一下效果,如下:v1.文件的上传   首先在ueditor/jsp目录下找到config.json文件,就拿Image上传来说吧。  "imageUrlPrefix": "http:/..._ueditor json = new function("return " + result)();

20、NanoDet训练、测试 以及使用ncnn部署Jetson Nano 进行目标检测和串口数据转发-程序员宅基地

文章浏览阅读6.5k次,点赞7次,收藏59次。基本思想:最近想尝试一下nano 上部署nanodet,于是记录一下训练过程,手中有一份labelme标注的数据集,于是开始了一波操作~首先将图片和json数据集转成xml (https://blog.csdn.net/sxj731533730/article/details/90046780),然后将xml数据集转成voc;import sysimport osimport jsonimport xml.etree.ElementTree as ETfrom PIL import Im_nanodet

code::blocks + wxWidgets 2.8 在ubuntu 10.04下的安装-程序员宅基地

文章浏览阅读930次。code::blocks + wxWidgets 2.8 在ubuntu 10.04下的安装p { margin-bottom: 0.21cm; }1、首先安装必要组件代码:安装编译器 sudo apt-get install build-essential

用java Swing做的小游戏"像素鸟"_java swing小游戏-程序员宅基地

文章浏览阅读4.4k次,点赞10次,收藏38次。最终效果 整个项目都是基于swing实现的。窗是口将图片加载到JPanel面板,然后将面板添加到到JFrame窗口实现显示。这个类是选择几只像素鸟的类,也是main函数里执行的方法,代码有详细的注释,这里就不废话了public class select extends JPanel { /** * */ private static final long serialVersio..._java swing小游戏

三分钟教你读懂支票是什么_支票的原理是什么-程序员宅基地

文章浏览阅读8.7k次。三分钟教你读懂支票是什么支票1、支票的概念及特点支票:出票人签发的,委托办理支票存款业务的银行或其他金融机构在见票时无条件支付确定金额给收款人或持票人的票据。支票必填项:支票字样、确定的金额、出票日期、无条件支付委托、付款人名称、出票人签章。支票选填项:付款地、出票地。支票结算特点:(1)简便,手续_支票的原理是什么

随便推点

P5738 【深基7.例4】歌唱比赛-程序员宅基地

文章浏览阅读311次。题目描述n(n\le 100)n(n≤100)名同学参加歌唱比赛,并接受m(m\le 20)m(m≤20)名评委的评分,评分范围是 0 到 10 分。这名同学的得分就是这些评委给分中去掉一个最高分,去掉一个最低分,剩下m-2m−2个评分的平均数。请问得分最高的同学分数是多少?评分保留 2 位小数。输入格式无输出格式无输入输出样例输入 ..._【深基7.例4】歌唱比赛

Vue简明实用教程(04)——事件处理_vue html里面如何直接写事件函数-程序员宅基地

文章浏览阅读1.1k次,点赞4次,收藏5次。在Vue中可非常便利地进行事件处理,例如:点击事件、鼠标悬停事件等。_vue html里面如何直接写事件函数

南京邮电大学离散数学实验一(求主析取和主合取范式)-程序员宅基地

文章浏览阅读4.5k次,点赞15次,收藏67次。南京邮电大学离散数学实验一(求主析取和主合取范式)_离散数学实验

{spring.cloud.client.ipAddress}_spring.cloud.client.ip-address-程序员宅基地

文章浏览阅读1.5w次,点赞2次,收藏5次。1.在springcloud中服务的 Instance ID 默认值是:${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}},也就是:主机名:应用名:应用端口。如图12.可以自定义:eureka.instance...._spring.cloud.client.ip-address

单目标跟踪OTB、VOT数据集介绍_otb数据集官网-程序员宅基地

文章浏览阅读2.1w次,点赞6次,收藏63次。OTB分为:OTB50和OTB100官方下载链接为:OTB官方数据集网站http://cvlab.hanyang.ac.kr/tracker_benchmark/datasets.html百度云链接:链接:https://pan.baidu.com/s/1Ck51d7OQ8w8BGcTL9UtopA提取码:jn0k复制这段内容后打开百度网盘手机App,操作更方便哦其中50和100,分别..._otb数据集官网

Xcode修改模拟器Simulator系统版本_xcode模拟器切换ios版本-程序员宅基地

文章浏览阅读5.1k次。从Xcode菜单栏里打开Xcode -> Preferences -> Components -> Simulators,下载对应版本的模拟器。由于模拟器相关文件较大,下载时间较长,需要耐心等待,下载完成后,对应版本的模拟器前面的下载按钮就会变成下载完成的样式。点击Xcode菜单栏 Window -> Devices,然后可以看到设备列表,然而在模拟器列表(..._xcode模拟器切换ios版本