菜单

React Native 中的 Flexbox

相关源文件

React Native 中的 Flexbox 提供了一个强大而直观的布局系统,用于在各种屏幕尺寸和方向上创建响应式 UI。本文档通过 Yoga 布局引擎解释了 Flexbox 在 React Native 中的工作原理,Yoga 是一个自定义的 C++ 实现,遵循 CSS Flexbox 规范,并包含一些 React Native 特有的行为。

有关 React Native 中更广泛的布局过程的信息,请参阅 布局引擎

Yoga 布局引擎概述

React Native 通过 Yoga 实现 Flexbox 规范。Yoga 是一个用 C++ 编写的跨平台布局引擎。Yoga 将 React Native 的样式属性转换为布局计算,从而确定组件在屏幕上的尺寸和位置。

Yoga 布局引擎处理:

  • 布局方向 (LTR/RTL)
  • Flex 分配
  • 对齐
  • 尺寸和定位
  • 外边距、内边距和边框

来源

核心 Flexbox 概念

Flex 方向

Flex 项目放置的主要轴。

属性描述
flexDirection定义主轴'row', 'row-reverse', 'column', 'column-reverse'

React Native 根据 Flex 方向确定主轴和交叉轴。

来源

Flex 容器属性

应用于父容器的属性,影响子项的布局方式。

属性描述默认
flexDirection主轴方向'column'
flexWrap项目是否可以换行'nowrap'
justifyContent主轴上的对齐方式'flex-start'
alignItems交叉轴上的对齐方式'stretch'
alignContent多行时的对齐方式'flex-start'

来源

Flex 项目属性

应用于子项的属性,影响它们的增长、收缩和自身定位。

属性描述默认
flex设置 flex 增长、收缩和基数的简写0
flexGrow在需要时增长的能力0
flexShrink在需要时收缩的能力0 (Web 默认值为 1)
flexBasis在分配空间之前的默认大小'auto'
alignSelf覆盖父项的 alignItems'auto'

来源

Flexbox 布局计算过程

Yoga 中的布局计算遵循一个多步过程:

来源

步骤 1:计算 Flex 基数

在布局开始之前,Yoga 会为每个子项计算 Flex 基数。

  1. 如果子项具有显式的 flexBasis,则使用该值。
  2. 如果没有,但它具有定义的宽度/高度(取决于主轴),则使用该值。
  3. 否则,将测量子项,其测量大小将成为 Flex 基数。

来源

步骤 2:收集 Flex 行

Yoga 根据可用空间和换行行为将项目分组到 Flex 行中。

  1. 对于不换行的布局,所有项目都放在一行中。
  2. 对于换行的布局,会收集项目直到它们超出可用空间,然后开始新的一行。

来源

步骤 3:分配剩余空间

一旦项目被分组到行中,剩余空间将根据 Flex 属性进行分配。

  1. 对于正的剩余空间,flexGrow 用于分配额外空间。
  2. 对于负的剩余空间,flexShrink 用于按比例收缩项目。
  3. 将进行两次传递以处理最小/最大约束。

来源

步骤 4:对齐项目

尺寸确定后,项目将被定位。

  1. 主轴定位根据 justifyContent
  2. 交叉轴定位根据 alignItemsalignSelf
  3. baseline 对齐的特殊处理。

来源

与 Web Flexbox 的区别

React Native 的实现与 Web Flexbox 之间有几个值得注意的区别:

  1. 默认值:

    • 在 React Native 中,默认的 flexDirection'column' (而不是 Web 上的 'row')。
    • 默认的 flexShrink0 (而不是 Web 上的 1)。
  2. 使用点而不是像素:React Native 使用设备无关点而不是像素。

  3. 默认尺寸:React Native 中的组件不会自动扩展以填充可用空间。

来源

排查 Flex 行为

当 Flex 布局不按预期工作时,请检查:

  1. 父容器尺寸:确保父容器具有定义的宽度和高度。

  2. flexGrow 与 flex:请记住 flex: 1{ flexGrow: 1, flexShrink: 1, flexBasis: 0 } 的简写,但 React Native 的默认值与 Web 不同。

  3. 绝对定位:绝对定位的项目会脱离 Flex 流程,不会影响其他项目。

  4. 嵌套的 Flex 容器:每个 Flex 容器建立自己的上下文;具有冲突方向的嵌套容器可能会导致问题。

来源

性能考量

Flexbox 布局计算可能非常耗费性能,尤其是在组件树很深的情况下。优化技巧:

  1. Memoize 样式:避免在每次渲染时创建新的样式对象。

  2. 尽可能使用固定尺寸:不要什么都依赖 Flex;当尺寸已知时,请指定它们。

  3. 避免深度嵌套:更扁平的组件层级计算速度更快。

  4. 使用 position: 'absolute' 对于不影响其他项目布局的元素。

  5. 考虑使用 shouldComponentUpdateReact.memo 以防止不必要的重新计算。

来源

结论

理解 Flexbox 在 React Native 中的工作方式对于创建响应式、跨平台布局至关重要。虽然 Yoga 实现核心 Flexbox 规范,但了解 React Native 特有的行为和优化将有助于您构建更可预测、性能更好的 UI。