[TOC]
# 1. 前言
本篇文章中将简单讲解下什么事离屏绘制。在Android中简要来说也就是将要绘制的内容单独绘制在缓冲层,而在Android中提供了canvas.saveLayer方法来保存当前图层作为离屏缓冲,在绘制完毕后可以使用canvas.restoreToCount(saveId)或者canvas.restore();来恢复之前的图层。这是什么意思呢?不妨来做一个简单的小实验:
比如,我这里的需求为绘制两个圆,并且让两个圆分开间隔20dp,水平对齐。当然,这里不直接产生两个已经满足条件的圆,而是使用这里的离屏绘制,也就是新增一个图层。假定两个圆的位置如下:
![](https://img.kancloud.cn/c5/ed/c5edb44a6db8108292e6b7b260704541_518x334.png)
对应代码:
~~~
private lateinit var mOtherPaint: Paint
private lateinit var mPaint: Paint
// 圆中心和半径
private var mCx = 300
private var mCy = 300
private var mRadius = 100
private fun init(){
mPaint = Paint()
mPaint.isAntiAlias = true
mPaint.color = Color.RED
mPaint.isDither = true
mPaint.strokeWidth = 5f
mPaint.style = Paint.Style.FILL
mOtherPaint = Paint()
mOtherPaint.isAntiAlias = true
mOtherPaint.color = Color.BLUE
mOtherPaint.isDither = true
mOtherPaint.strokeWidth = 5f
mOtherPaint.style = Paint.Style.FILL
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.apply {
// 只有一个图层情况
drawCircle(mCx.toFloat(), mCy.toFloat(), mRadius.toFloat(), mPaint)
drawCircle(mCx.toFloat() + 50, mCy.toFloat() + 50, mRadius.toFloat(), mOtherPaint)
}
}
~~~
如果只有一个图层,那么我们就需要修改两个圆的坐标位置。这里我们使用新建一个图层的方式。也就是:
~~~
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
canvas?.apply {
// 只有一个图层情况
drawCircle(mCx.toFloat(), mCy.toFloat(), mRadius.toFloat(), mPaint)
// 存储当前图层
val saveLayerId = saveLayer(0f, 0f, width.toFloat(), height.toFloat(), mPaint)
// 移动画布
translate((20 + mRadius * 2).toFloat(), 0f)
drawCircle(mCx.toFloat(), mCy.toFloat(), mRadius.toFloat(), mOtherPaint)
// 恢复之前图层
restoreToCount(saveLayerId)
}
}
~~~
结果:
![](https://img.kancloud.cn/6e/ce/6ece7eab38a0b5b57790afce682e81ad_209x106.png)
从结果中可以看出,其实这里可以理解为创建了一个新的图层,然后可以对新图层进行简单平移操作,然后绘制对应的图层内容,继而最终在上一个图层恢复的时候可以将多个(两个)图层合并。
# 2. 其他
View.setLayerType()直接把整个View都绘制在离屏缓冲中
```java
//使用一个Bitmap来缓冲,通常也就是设置禁用硬件加速
setLayerType(LAYER_TYPE_SOFTWARE, null);
//使用GPU来缓冲
setLayerType(LAYER_TYPE_HARDWARE, null);
```
- 介绍
- UI
- MaterialButton
- MaterialButtonToggleGroup
- 字体相关设置
- Material Design
- Toolbar
- 下拉刷新
- 可折叠式标题栏
- 悬浮按钮
- 滑动菜单DrawerLayout
- NavigationView
- 可交互提示
- CoordinatorLayout
- 卡片式布局
- 搜索框SearchView
- 自定义View
- 简单封装单选
- RecyclerView
- xml设置点击样式
- adb
- 连接真机
- 小技巧
- 通过字符串ID获取资源
- 自定义View组件
- 使用系统控件重新组合
- 旋转菜单
- 轮播图
- 下拉输入框
- 自定义VIew
- 图片组合的开关按钮
- 自定义ViewPager
- 联系人快速索引案例
- 使用ListView定义侧滑菜单
- 下拉粘黏效果
- 滑动冲突
- 滑动冲突之非同向冲突
- onMeasure
- 绘制字体
- 设置画笔Paint
- 贝赛尔曲线
- Invalidate和PostInvalidate
- super.onTouchEvent(event)?
- setShadowLayer与阴影效果
- Shader
- ImageView的scaleType属性
- 渐变
- LinearGradient
- 图像混合模式
- PorterDuffXfermode
- 橡皮擦效果
- Matrix
- 离屏绘制
- Canvas和图层
- Canvas简介
- Canvas中常用操作总结
- Shape
- 圆角属性
- Android常见动画
- Android动画简介
- View动画
- 自定义View动画
- View动画的特殊使用场景
- LayoutAnimation
- Activity的切换转场效果
- 属性动画
- 帧动画
- 属性动画监听
- 插值器和估值器
- 工具
- dp和px的转换
- 获取屏幕宽高
- JNI
- javah命令
- C和Java相互调用
- WebView
- Android Studio快捷键
- Bitmap和Drawable图像
- Bitmap简要介绍
- 图片缩放和裁剪效果
- 创建指定颜色的Bitmap图像
- Gradle本地仓库
- Gradle小技巧
- RxJava+Okhttp+Retrofit构建网络模块
- 服务器相关配置
- node环境配置
- 3D特效