Android 自定义控件基础:draw过程

draw过程是将View绘制到屏幕上。在这个过程中 View 需要通过操作 Canvas 来实现自己 UI 效果。

ViewRootImpl

View 的 draw 起始点也是从 ViewRootImpl 开始的,ViewRootImpl 的 performDraw 方法最终会调用 drawSoftware 方法,再通过调用 DecorView 的 draw 方法来启动 draw 流程。

// ViewRootImpl 类源码

private void performTraversals() {
   
  if (!cancelDraw) {
   
      ...
      performDraw();
  }
  ...
}

private void performDraw() {
   
  try {
   
        ....
        boolean canUseAsync = draw(fullRedrawNeeded);
        ....
      } finally {
   
            ....
      }    
}

private boolean draw(boolean fullRedrawNeeded) {
   
    ....
    if (!dirty.isEmpty() || mIsAnimating || accessibilityFocusDirty) {
   
        if (mAttachInfo.mThreadedRenderer != null && mAttachInfo.mThreadedRenderer.isEnabled()) {
   
            ...
        }else {
   
            ...
            if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
                        scalingRequired, dirty, surfaceInsets)) {
   
                    return false;
            }
        }
    }
}

private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
   
    final Canvas canvas;
    ...
    try {
   
        ...
        mView.draw(canvas);
        ...
    }finally {
   
        ...
    }
    
    return true;
}

View

View 的draw方法的重点关注调用的 onDraw 和 dispatchDraw 这两个方法

/ View draw 源码

public void draw(Canvas canvas) {
   
       ....
       
        // Step 1, draw the background, if needed
        //绘制当前视图的背景
        int saveCount;

        drawBackground(canvas);

        // skip step 2 & 5 if possible (common case)
        final int viewFlags = mViewFlags;
        
        // 获得当前视图View水平或者垂直方向是否需要绘制边框渐变效果,如果不需要绘制边框的渐变效果,就无需执行2,5了,那么就直接执行的3,4,6步骤
        boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0;
        boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0;
        
        if (!verticalEdges && !horizontalEdges) {
   
            // Step 3, draw the content
            // 绘制内容
            onDraw(canvas);

            // Step 4, draw the children
            // 绘制子View
            dispatchDraw(canvas);

            drawAutofilledHighlight(canvas);

            // Overlay is part of the content and draws beneath Foreground
            if (mOverlay != null && !mOverlay.isEmpty()) {
   
                mOverlay.getOverlayView().dispatchDraw(canvas);
            }

            // Step 6, draw decorations (foreground, scrollbars)
            // 绘制装饰(前景色、滚动条)
            onDrawForeground(canvas);

            // Step 7, draw the default focus highlight
            drawDefaultFocusHighlight(canvas);

            if (isShowingLayoutBounds()) {
   
                debugDrawFocus(canvas);
            }

            // we're done...
            return;
        }
        
        // 下面代码用来检查是否需要保存参数canvas所描述的一块画布的堆栈状态,
        // 并且创建额外的图层来绘制当前视图在滑动时的边框渐变效果
        boolean drawTop = false;
        boolean drawBottom = false;
        boolean drawLeft = false;
        boolean drawRight = false;

        
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值