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

智能推荐

As you develop your lead qualification criteria-程序员宅基地

文章浏览阅读126次。While you have on your own the Christian Louboutin replicas they enable you to definitely present the average pe...

浅谈go语言channel通道造成的死锁问题_go 线上环境 channel死锁怎么解决-程序员宅基地

文章浏览阅读581次。浅谈go语言channel通道造成的死锁问题_go 线上环境 channel死锁怎么解决

ElasticSearch文本分析(一)-程序员宅基地

文章浏览阅读682次。文章目录ElasticSearch文本分析(一)概述分词归一化自定义文本分析器概念分析器的剖析字符过滤器分词器分词过滤器索引和查询分析词干提取词干提取分词过滤器算法词干提取器词典词干提取器配置文本分析测试分析器配置内部分析其内部分析器参考指纹分析器示例输出配置配置例子定义`keyword`分析器例子输出配置定义语言分析器模式分析器例子输出配置配置实例驼峰分词器定义简单的分析器例子定义自定义标准分析器例子配置配置例子定义停用词分析器例子:配置配置例子:定义空格分析器例子配置定义ElasticSearch文本_elasticsearch文本分析

华科CPP慕课SPOC第七章 编程题3_请完整戏票类的实现代码。并使用测试代码测试该类,测试代码的运行结果应和输出样-程序员宅基地

文章浏览阅读1.6k次,点赞5次,收藏5次。作业_请完整戏票类的实现代码。并使用测试代码测试该类,测试代码的运行结果应和输出样

【数据结构实验】查找(一)基于散列表的查找算法-程序员宅基地

文章浏览阅读1k次,点赞20次,收藏20次。本实验将通过C语言实现基于散列表的查找算法

Excel宏的录制和解密_录制宏,要求对象 columns-程序员宅基地

文章浏览阅读2.1k次。本篇演示的Excel版本:Excel 2019本篇演示一个简单的宏的录制。 实现的效果是将 Sheet1 的A 列 复制到到Sheet2 的 A 列。宏的录制和保存步骤打开Excel点击上方菜单的 “视图”, 点击 “宏 ”, 在下拉菜单中选择录制宏。在弹出对话框中,给宏取个名字后点击“确定”在Sheet1 中选择 A 列, 复制后粘贴到 sheet 2的A列, 在到“宏” 菜单中点击“停止录制”在点击保存的时候会弹出一个提示框,注意: 如果要保存宏, 要点击“否_录制宏,要求对象 columns

随便推点

Java集合详解1:ArrayList,Vector与Stack_arraylist stack-程序员宅基地

文章浏览阅读6.1k次,点赞16次,收藏23次。本文非常详尽地介绍了Java中的三个集合类 ArrayList,Vector与Stack”Java集合详解系列“是我在完成Java基础篇的系列博客后准备开始写的新系列。Java集合系列专栏地址:https://blog.csdn.net/column/details/21877.html之前的Java基础系列博客首发于我的个人博客:https://h2pl.github.io/在..._arraylist stack

浅谈概率与数学期望问题_数学期望的递推关系-程序员宅基地

文章浏览阅读930次。浅谈概率与数学期望问题_数学期望的递推关系

如何实现PLC发短信、发微信、打电话拨号语音_plc发送短信-程序员宅基地

文章浏览阅读116次。​现场PLC监控到运行数据有异常,怎样实现通过短信/微信/拨打电话通知值班人员呢?可以通过增加巨控的GRM系列模块来实现。巨控远程模块通过RS 485/RS232/RJ45和PLC通讯,将PLC的数据读入到GRM模块,再编辑报警条件,就依据数据是否满足触发条件,用巨控模块的短信功能/微信功能/电话拨号功能来实现。_plc发送短信

python编程-用flask写出第一个程序_flask_app = main.py flask_env = development flask_-程序员宅基地

文章浏览阅读160次。from flask import Flask # 从flask包中导入Flask类app = Flask(__name__)# 实例化一个app对象@app.route('/') # 把括号中的参与被装饰的函数链接到一起def hello_world(): return 'Hello World!'if __name__ == '__main__': app.run() # 默认是5000端口执行结果:FLASK_APP = app.pyFLASK_ENV = d_flask_app = main.py flask_env = development flask_debug = 0 in folder d:/pro

java笔试题_d) -个线程可能因为不同的原因停止并进入就绪状态-程序员宅基地

文章浏览阅读856次,点赞3次,收藏6次。1,有关线程的哪些叙述是对的( ) A,一旦一个线程被创建,它就立即开始运行。 B,使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行。 C,当一个线程因为抢先机制而停止运行,它被放在可运行队列的前面。 D,一个线程可能因为不同的原因停止并进入就绪状态。答案:BCD 在抢占式线_d) -个线程可能因为不同的原因停止并进入就绪状态

MySQL之视图详解_mysql视图-程序员宅基地

文章浏览阅读1.1k次,点赞19次,收藏20次。视图(view)是一种虚拟存在的表,视图中的数据并不在数据库中实际存在,视图中的数据来自定义视图时select查询的表,并且视图是动态生成的。通俗的讲:视图只保存了select的SQL逻辑,不保存查询结果。所以我们在创建视图时,主要工作就落在创建select查询语句上。MySQL 视图是一个虚拟的表,它由一个 SQL 查询定义,并且不存储实际的数据。视图的数据来自于查询执行的结果,并且可以像表一样被查询、更新和删除。视图提供了一种简化复杂查询的方法,并且可以用来限制用户对数据库中特定数据的访问。_mysql视图

推荐文章

热门文章

相关标签