返回

布局测量中的高深艺术

Android

从某种意义上说,要理解如何自定义一个ViewGroup的测量和布局其实并不是一件容易的事。大多数人对自定义ViewGroup的布局和测量的了解仅限于网上随处可见的TagLayout的写法(对TagLayout还不清楚的同学建议都去搜搜看)。但是,大多数人在看完以后仍然是一头雾水,不知道为什么这样做。

自定义ViewGroup的布局测量过程

自定义ViewGroup的布局测量过程主要分为两部分:测量和布局。

  1. 测量

测量过程负责计算ViewGroup及其子视图的大小。在测量过程中,ViewGroup会遍历其所有子视图,并调用每个子视图的onMeasure()方法来计算子视图的大小。子视图的大小可以通过以下方式之一确定:

  • 明确指定大小 :如果子视图的大小由其布局参数明确指定,则ViewGroup将使用该大小。
  • 测量子视图 :如果子视图的大小没有由其布局参数明确指定,则ViewGroup将测量子视图以确定其大小。
  • 依赖其他子视图 :如果子视图的大小依赖于其他子视图的大小,则ViewGroup将等待其他子视图的测量结果,然后再计算子视图的大小。
  1. 布局

布局过程负责将子视图放置在ViewGroup中。在布局过程中,ViewGroup会遍历其所有子视图,并调用每个子视图的onLayout()方法来指定子视图的位置。子视图的位置可以通过以下方式之一确定:

  • 绝对定位 :如果子视图的位置由其布局参数绝对指定,则ViewGroup将子视图放置在指定的位置。
  • 相对定位 :如果子视图的位置由其布局参数相对指定,则ViewGroup将子视图放置在相对位置。
  • 依赖其他子视图 :如果子视图的位置依赖于其他子视图的位置,则ViewGroup将等待其他子视图的布局结果,然后再计算子视图的位置。

技巧和最佳实践

  • 使用MeasureSpec对象来指定子视图的大小和位置。MeasureSpec对象包含两个值:modesizemode值指定了子视图的大小是否受到限制,而size值指定了子视图的大小限制。
  • 使用LayoutParams对象来指定子视图的布局参数。LayoutParams对象包含了子视图的大小和位置信息。
  • 使用onMeasure()onLayout()方法来测量和布局子视图。onMeasure()方法负责计算子视图的大小,而onLayout()方法负责将子视图放置在ViewGroup中。
  • 使用invalidate()requestLayout()方法来强制ViewGroup重新测量和布局其子视图。invalidate()方法强制ViewGroup重新测量其子视图,而requestLayout()方法强制ViewGroup重新测量和布局其子视图。