type
status
date
slug
summary
tags
category
password
icon

布局流程

布局过程

  • 确定每个 View 的位置和尺⼨
  • 作⽤:为绘制和触摸范围做⽀持
    • 绘制:知道往哪⾥绘制
    • 触摸反馈:知道⽤户点的是哪⾥

流程

从整体看:

  • 测量流程:从根 View 递归调⽤每⼀级⼦ View 的 measure() ⽅法,对它们进⾏测量
  • 布局流程:从根 View 递归调⽤每⼀级⼦ View 的 layout() ⽅法,把测量过程得出的⼦ View 的位置和尺⼨传给⼦ View,⼦ View 保存
  • 为什么要分两个流程? 因为可能会重复测量

从个体看,对于每个 View:

  • 运⾏前,开发者在 xml ⽂件⾥写⼊对 View 的布局要求 layout_xxx
  • ⽗ View 在⾃⼰的 onMeasure() 中,根据开发者在 xml 中写的对⼦ View 的要求,和⾃⼰的可⽤空间,得出对⼦ View 的具体尺⼨要求
  • ⼦ View 在⾃⼰的 onMeasure() 中,根据⽗ View 的要求和⾃⼰的特性算出⾃⼰的期望尺⼨
  • 如果是 ViewGroup,还会在这⾥调⽤每个⼦ View 的 measure() 进⾏测量
  • ⽗ View 在⼦ View 计算出期望尺⼨后,得出⼦ View 的实际尺⼨和位置
  • ⼦ View 在⾃⼰的 layout() ⽅法中,将⽗ View 传进来的⾃⼰的实际尺⼨和位置保存
    • 如果是 ViewGroup,还会在 onLayout() ⾥调⽤每个⼦ View 的 layout() 把它们的尺⼨位置传给它们
 

尺寸的自定义

简单改写已有 View 的尺⼨

  • 重写 onMeasure()
  • getMeasuredWidth()getMeasuredHeight() 获取到测量出的尺⼨
  • 计算出最终要的尺⼨
  • setMeasuredDimension(width, height) 把结果保存
  • 例⼦:SquareImageView
  • 为什么不重写 layout()?
    • 因为重新 layout() 会导致「不听话」(父View无法知道layout中做了哪些变化)
       
💡
设置View的内边距的方法

完全⾃定义 View 的尺⼨

  • 重写 onMeasure()
  • 计算出⾃⼰的尺⼨
    • MeasureSpec.EXACTLY → 精确值,所以就用父View传过来的值
    • MeasureSpec.AT_MOST → 最大限制值,不允许超过
    • MeasureSpec.UNSPECIFIED → 无限制
  • 由于上一步中基本都是定好的规则,代码逻辑大部分是死的,所以官方封装了 resolveSize()resolveSizeAndState() 用于完成上一步操作,并修正结果
  • 使⽤ setMeasuredDimension(width, height) 保存结果
  • 例⼦:CircleView
 

Layout 的⾃定义

⾃定义 Layout

  • 重写 onMeasure()
    • 遍历每个⼦ View,测量⼦ View
      • 测量完成后,得出⼦ View 的实际位置和尺⼨,并暂时保存
        • 上面的策略子View的规则,基本上也是写死的一套规则,所以View中提供了一个方法
      • 有些⼦ View 可能需要重新测量
    • 测量出所有⼦ View 的位置和尺⼨后,计算出⾃⼰的尺⼨,并⽤setMeasuredDimension(width, height) 保存
  • 重写 onLayout()
    • 遍历每个⼦ View,调⽤它们的 layout() ⽅法来将位置和尺⼨传给它们
     
    Styleable属性动画和硬件加速
    Loading...
    shuouyang
    shuouyang
    android开发 ReactNative开发 小程序开发
    最新发布
    AOSP 环境搭建
    2025-3-29
    View 绘制流程-源码解析
    2025-3-12
    HTTP
    2025-3-4
    JVM 虚拟机
    2025-2-28
    蓝牙-BLE-基础
    2025-2-28
    从 OkHttp 的原理来看 HTTP
    2025-2-19
    公告
    🎉热点信息🎉
    --- 1 ---
    Jet Brains 推出新的跨平台支持 Kotlin MultiPlatform
    --- 2 ---
    新的小巧便捷的依赖注入框架 Koin
    --- 3 ---
    新一代 API 查询语言 GraphQL