Android UI 绘制流程及原理

View添加到窗口中的流程

  1. 创建 DecorView,顶层容器,继承于 FrameLayout。
  2. 根据主题不同,创建不同的基础容器ViewGroup(如: R.layout.screen_simple,是一个线性布局),并添加到 decorView 中。
  3. 基础容器中,有一个ID为 Window.ID_ANDROID_CONTENT(com.android.internal.R.id.content)的FrameLayout布局容器,这个容器就是contentView。开发者调用的 setContentView 方法,就是将自定义的容器追加到 contentView 中。

类图
在这里插入图片描述

  • Window是一个抽象类,定义了绘制窗口的API
  • PhoneWindow是Window具体实现类,该类内部包含DecorView对象。DecorView是所有应用窗口(Activity)的根View,DecorView是PhoneView的内部类,是FrameLayout的子类。

View的绘制流程

  1. 绘制入口
ActivityThread.handlerResumeActivity 
--> WidowManagerImpl.addView(decorView, layoutParams)
--> WindowManagerGlobal.addView()
  1. 绘制的类和方法
ViewRootImpl.setVIew(decorView, layoutParams, parentView)
-->ViewRootImpl.requestLayout()
-->scheduleTraversals() --> doTraversals() --> performTravesals()
  1. 三步骤
ViewRootImpl.performMeasure //测量 
ViewRootImpl.performLayout // 布局
ViewRootImpl.performDraw // 绘制

测量

测量View = 模式 + 尺寸 -> MeasureSpec 32int值
模式: 
    EXACTLY : 精确
    AT_MOST : 最大
    UNSPECIFIED : 
    
MeasureSpec = SpecMode(2) + SpecSize(30)
ViewGroup 容器测量 : measure  -> onMeausre(测量子控件的宽高) -> setMeasuredDimension() -> setMeasuredDimensionRaw(保存自己的宽高)
View measure : measure -> onMeasure(仅测量自己) -> setMeasuredDimension() -> setMeasuredDimensionRaw(保存自己的宽高)

布局

ViewGroup 是一个容器

  1. 调用 view.layout 确定自身的位置,即mLeft,mTop,mRirht,mBottom
  2. 如果是 ViewGroup 类型(容器类型),需要调用 onLayout 确定子 View 的位置(递归调用)

绘制

  1. 绘制背景 :drawBackground(canvas)
  2. 绘制自己 :onDraw(canvas)
  3. 绘制子VIew (如果是ViewGroup):dispatchDraw(canvas)
  4. 绘制前景,滚动条等装饰 :onDrawForeground(canvas)

自定义VIew需要重写的方法

onMeasue() -> onLayout(容器) -> [onDraw]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值