【view】- 绘制流程

简介

这篇文章继续就上一篇文章【View】- setContentView方法和UI绘制流程(源码分析)中performDraw方法进行讲解,了解UI绘制的布局过程。如果想了解测量流程,请查看【view】- 测量流程。
如果想了解测量流程,请查看【view】- 布局流程

performDraw

读过【View】- setContentView方法和UI绘制流程(源码分析)应该知道,performDraw中的mView是顶层布局DecorView。

private void performDraw() {
    ...
    draw(fullRedrawNeeded);
    ...
}

获取mDirty,该值表示需要重绘的区域。

如果fullRedrawNeeded为真,则把dirty区域置为整个屏幕,表示整个视图都需要绘制。

if (fullRedrawNeeded) {
    mAttachInfo.mIgnoreDirtyState = true;
    dirty.set(0, 0, (int) (mWidth * appScale + 0.5f), (int) (mHeight * appScale + 0.5f));
}

通知注册的侦听器绘图过程即将开始

mAttachInfo.mTreeObserver.dispatchOnDraw();

调用drawSoftware方法,这个方法首先是实例化了Canvas对象,然后锁定该canvas的区域,由dirty区域决定,接着对canvas进行一系列的属性赋值,最后调用了mView.draw(canvas)方法,那么之前就讲过这里的mView就是我们的DectorView所以是从DectorView顶层开始绘制 那么之前的一切都是在进行准备一块画板具体的绘制实在mView.draw当中,这里将画板给入,而现在则是正式开始绘制流程。

调用DectorView的draw方法,先看一下View中draw方法的实现。

  • 绘制背景
if (!dirtyOpaque) {
   drawBackground(canvas);
}

标记位dirtyOpaque,该标记位的作用是判断当前View是否是透明的,如果View是透明的,那么根据下面的逻辑可以看出,将不会执行一些步骤,比如绘制背景、绘制内容等。这样很容易理解,因为一个View既然是透明的,那就没必要绘制它了 。

绘制总结
1、对View的背景进行绘制
2、保存当前的图层信息
3、绘制View的内容

if (!dirtyOpaque) onDraw(canvas);

onDraw,View中该方法是一个空实现,这里同理于之前的onMeasure和onLayout因为不同的View有着不同的内容,这需要我们自己去实现,即在自定义View中重写该方法来实现。

4、对View的子View进行绘制(如果有子View,会调用子View的draw(canvas, this, drawingTime)方法。

5、绘制View的褪色的边缘,类似于阴影效果

6、绘制View的装饰,比如foreground, scrollbars

7、在画布上绘制默认的焦点高光

具体实现请自己看代码,如果前面都能够看懂,那么相信也能大致看懂里面的执行过程。

你可能感兴趣的:(【view】- 绘制流程)