不会吧!学Android你不知道View的绘制流程?

“我不再寻找好运,我自己就是好运。”

你这小小的碎片知识——View的绘制流程。
拿来吧你,直接美美的拿捏。
在这里插入图片描述

1.绘制流程

来跟我记。

  1. 当点击App启动的时候,启动了Activity。
  2. 一个Activity对应的会有三个Window,一个是关于Activity,一个是Dialog,一个是Toast。(这也是Dialog和Toast不能影响Activity的生命周期的原因)
  3. Window是一个抽象基类,是 Activity 和整个 View 系统交互的接口,只有一个子类实现类PhoneWindow。
  4. 我们显示的视图是在DecorView上。
  5. ViewRootImpl 就是建立 DecorView 和 Window 之间的联系。
  6. 整体视图情况如下:
    在这里插入图片描述

2.主流程

当应用启动时,会启动一个主 Activity,系统会根据 Activity 的布局来对它进行绘制。绘制会从根视图 ViewRoot 的 performTraversals() 方法开始。

performTraversals 方法在类 ViewRootImpl 内,其核心代码如下。
int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
...
// 测量
performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
...
// 布局
performLayout(lp, mWidth, mHeight);
...
// 绘制
performDraw();

3.MeasureSpec(测量模式)

  1. UNSPECIFIED:不指定测量模式,父视图没有限制子视图的大小,子视图可以是想要的任何尺寸,通常用于系统内部,应用开发中很少使用到。
  2. EXACTLY:精确测量模式,当该视图的 layout_width 或者 layout_height 指定为具体数值或者 match_parent 时生效,表示父视图已经决定了子视图的精确大小,这种模式下 View 的测量值就是 SpecSize 的值。
  3. AT_MOST:最大值模式,当前视图的 layout_width 或者 layout_height 指定为 wrap_content 时生效,此时子视图的尺寸可以是不超过父视图运行的最大尺寸的任何尺寸。

4.Measure(测量)

  1. Measure 用来计算 View 的实际大小。页面的测量流程从 performMeasure 方法开始。
  2. 具体操作是分发给 ViewGroup 的,由 ViewGroup 在它的 measureChild 方法中传递给子 View。ViewGroup 通过遍历自身所有的子 View,并逐个调用子 View 的 measure 方法实现测量操作。
  3. View (ViewGroup) 的 Measure 方法,最终的测量是通过回调 onMeasure 方法实现的,这个通常由 View 的特定子类自己实现,可以通过重写这个方法实现自定义 View。

5.Layout(位置)

Layout 过程用来确定 View 在父容器的布局位置,他是父容器获取子 View 的位置参数后,调用子 View 的 layout 方法并将位置参数传入实现的。

6.Draw(绘制)

绘制基本上可以分为六个步骤。

public void draw(Canvas canvas) {
  ...
  // Step 1, draw the background, if needed
  if (!dirtyOpaque) {
    drawBackground(canvas);
  }
  ...
  // Step 2, save the canvas' layers
  saveCount = canvas.getSaveCount();
  ...
  // Step 3, draw the content
  if (!dirtyOpaque) onDraw(canvas);

  // Step 4, draw the children
  dispatchDraw(canvas);

  // Step 5, draw the fade effect and restore layers
  canvas.drawRect(left, top, right, top + length, p);
  ...
  canvas.restoreToCount(saveCount);
  ...
  // Step 6, draw decorations (foreground, scrollbars)
  onDrawForeground(canvas);
}

7.错误不足

请大佬私信指出。(心里默念,我是没错的)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值