- 一、Canvas 绘图源码分析
- 二、ViewRootImpl#draw 方法源码
- 三、ViewRootImpl#drawSoftware 方法源码
Canvas 状态保存机制 中 , 存在两个栈结构 , 分别是 状态栈 和 图层栈 ;
其中 图层栈 又称为 Layer 栈 ;
Canvas 画布中 , 有 2 2 2 套坐标系 , 分别是 :
- Canvas 自身坐标系
- Canvas 绘图坐标系
参考 【Android 应用开发】UI绘制流程 ( 生命周期机制 | 布局加载机制 | UI 绘制流程 | 布局测量 | 布局摆放 | 组件绘制 | 瀑布流布局案例 ) 博客 , Android 的 UI 界面绘制流程为 :
- 布局测量
- 布局摆放
- 组件绘制
这里 分析 Android 组件绘制过程中 , Canvas 画布相关操作 ;
在绘制时 , 最终调用的方法是 ViewRootImpl#draw 方法 , 在该方法中
Surface surface
是最终绘制的面板 ,
Surface surface = mSurface;
绘图时 , 首先要确认绘制区域 , 下面的代码就是 在 手机界面 中 定位出 绘制区域 用的 , 这块绘制区域 是属于 Surface 的 ,
final Rect dirty = mDirty;
if (mSurfaceHolder != null) {
// The app owns the surface, we won't draw.
dirty.setEmpty();
if (animating && mScroller != null) {
mScroller.abortAnimation();
}
return;
}
if (fullRedrawNeeded) {
mAttachInfo.mIgnoreDirtyState = true;
dirty.set(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
}
在该方法最后调用了 ViewRootImpl#drawSoftware 方法 , 进行下一步绘制操作 ;
if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)) {
return;
}
在 ViewRootImpl#drawSoftware 方法中 , 由 ViewRootImpl#mSurface 生成 Canvas 画布 , 并为 Canvas 设置绘制坐标 , Rect dirty 可以理解为 Canvas 的绘制坐标区域 ;
// Draw with software renderer.
final Canvas canvas;
try {
final int left = dirty.left;
final int top = dirty.top;
final int right = dirty.right;
final int bottom = dirty.bottom;
canvas = mSurface.lockCanvas(dirty);
// The dirty rectangle can be modified by Surface.lockCanvas()
//noinspection ConstantConditions
if (left != dirty.left || top != dirty.top || right != dirty.right
|| bottom != dirty.bottom) {
attachInfo.mIgnoreDirtyState = true;
}
// TODO: Do this in native
canvas.setDensity(mDensity);
}
二、ViewRootImpl#draw 方法源码
ViewRootImpl#draw 方法源码 :
public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
private void draw(boolean fullRedrawNeeded) {
// 具体绘画的面板
Surface surface = mSurface;
if (!surface.isValid()) {
return;
}
if (DEBUG_FPS) {
trackFPS();
}
if (!sFirstDrawComplete) {
synchronized (sFirstDrawHandlers) {
sFirstDrawComplete = true;
final int count = sFirstDrawHandlers.size();
for (int i = 0; i
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?