第42章 React Native 使用 Flexbox 进行布局
第42章:使用 Flexbox 进行布局
版本:0.77 组件可以通过 Flexbox 算法指定其子元素的布局。Flexbox 旨在提供不同屏幕尺寸下一致性的布局体验。
通常,你需要组合使用 flexDirection、alignItems 和 justifyContent 来实现理想的布局效果。
注意 在 React Native 中,Flexbox 的工作方式与 Web 上的 CSS 基本一致,但存在几处例外。
默认值有所不同:flexDirection 默认为 column 而非 row;alignContent 默认为 flex-start 而非 stretch;flexShrink 默认为 0 而非 1;flex 参数仅支持单个数字。
Flex flex 定义子项如何沿主轴“填充”可用空间。空间将根据每个元素的 flex 属性进行分配。
在以下示例中,红色、橙色和绿色视图都是容器的子元素,该容器设置了 flex: 1。红色视图使用 flex: 1,橙色视图使用 flex: 2,绿色视图使用 flex: 3。由于 1+2+3 = 6,这意味着红色视图获得 1/6 的空间,橙色视图获得 2/6 的空间,绿色视图获得 3/6 的空间。
Flex Direction flexDirection 控制子元素排列的方向,这也称为主轴。交叉轴是垂直于主轴的轴,或者是换行排列的轴。
* column (默认值):子元素从上到下排列。如果启用了换行,下一行将从容器顶部第一项的右侧开始。 * row:子元素从左到右排列。如果启用了换行,下一行将从容器左侧第一项的下方开始。 * column-reverse:子元素从下到上排列。如果启用了换行,下一行将从容器底部第一项的右侧开始。 * row-reverse:子元素从右到左排列。如果启用了换行,下一行将从容器右侧第一项的下方开始。
你可以在此查看更多内容。 TypeScript JavaScript
Layout Direction 布局方向指定了层级中子元素和文本排列的方向。布局方向还决定了 start 和 end 边缘指代的具体位置。默认情况下,React Native 采用 LTR 布局方向。在此模式下,start 指左侧,end 指右侧。
* LTR (默认值):文本和子元素从左向右排列。应用于元素 start 边缘的 margin 和 padding 会作用在左侧。 * RTL:文本和子元素从右向左排列。应用于元素 start 边缘的 margin 和 padding 会作用在右侧。
你可以在此查看更多内容。 TypeScript JavaScript
Justify Content justifyContent 描述子元素在其容器主轴上的对齐方式。例如,你可以使用此属性将子元素在 flexDirection 为 row 的容器中水平居中,或在 flexDirection 为 column 的容器中垂直居中。
* flex-start (默认值):将容器的子元素对齐到容器主轴的起始位置。 * flex-end:将容器的子元素对齐到容器主轴的末尾位置。 * center:将容器的子元素对齐到容器主轴的中心位置。 * space-between:在容器的子元素之间均匀分布剩余空间。 * space-around:围绕容器的子元素均匀分布剩余空间。与 space-between 相比,使用 space-around 会在第一个子元素的起始处和最后一个子元素的结束处也分配空间。 * space-evenly:沿主轴在对齐容器中均匀分布子元素。每对相邻项目之间、主轴起始边缘与第一个项目之间、以及主轴结束边缘与最后一个项目之间的间距完全相同。
你可以在此查看更多内容。 TypeScript JavaScript
Align Items alignItems 描述子元素在其容器交叉轴上的对齐方式。它与 justifyContent 非常相似,但 alignItems 作用于交叉轴,而非主轴。
* stretch (默认值):拉伸容器的子元素以匹配容器交叉轴的高度。 * flex-start:将容器的子元素对齐到容器交叉轴的起始位置。 * flex-end:将容器的子元素对齐到容器交叉轴的末尾位置。 * center:将容器的子元素对齐到容器交叉轴的中心位置。 * baseline:将容器的子元素沿公共基线对齐。可以单独设置某个子元素作为其父元素的参考基线。
提示 要使 stretch 生效,子元素在次轴上不能有固定尺寸。在以下示例中,除非移除子元素的 width: 50,否则设置 alignItems: stretch 没有任何效果。
你可以在此查看更多内容。 TypeScript JavaScript
Align Self alignSelf 拥有与 alignItems 相同的选项和效果,但它不作用于容器内的所有子元素,而是应用于单个子元素以改变其在父元素中的对齐方式。alignSelf 会覆盖由父元素通过 alignItems 设置的任何选项。
TypeScript JavaScript
Align Content alignContent 定义沿交叉轴对换行行进行分布。只有当使用 flexWrap 将项换行为多行时,此属性才有效。
* flex-start (默认值):将换行行对齐到容器交叉轴的起始位置。 * flex-end:将换行行对齐到容器交叉轴的末尾位置。 * stretch (在 Web 上使用 Yoga 时的默认值):拉伸换行行以匹配容器交叉轴的高度。 * center:将换行行对齐到容器交叉轴的中心位置。 * space-between:沿容器交叉轴均匀分布换行行,在行之间分配剩余空间。 * space-around:沿容器交叉轴围绕换行行均匀分布剩余空间。与 item 之间的空间相比,容器每端的空间大小减半。 * space-evenly:沿容器交叉轴围绕换行行均匀分布剩余空间。每个空间的大小相同。
你可以在此查看更多内容。 TypeScript JavaScript
Flex Wrap flexWrap 属性设置在容器上,控制当子元素沿主轴超出容器大小时发生什么。默认情况下,子元素被强制排成一行(这可能会导致元素缩小)。如果允许换行,必要时项目将沿主轴换行为多行。
在换行时,可以使用 alignContent 指定行在容器中的放置方式。在此了解更多信息。
TypeScript JavaScript
Flex Basis, Grow, and Shrink
* flexBasis 提供了一种不依赖轴的方式来提供项目沿主轴的默认尺寸。如果父容器 flexDirection 为 row,设置子元素的 flexBasis 类似于设置其宽度;如果父容器 flexDirection 为 column,则类似于设置其高度。项目的 flexBasis 是该项目的默认尺寸,即在计算 flexGrow 和 flexShrink 之前的尺寸。 * flexGrow 描述了容器内有多少空间应沿主轴分配给其子元素。在布局子元素后,容器将根据子元素指定的 flex grow 值分配剩余空间。flexGrow 接受任何大于或等于 0 的浮点值,默认值为 0。容器将根据子元素的 flexGrow 值加权分配剩余空间。 * flexShrink 描述了当子元素的总尺寸沿主轴超出容器大小时,如何沿主轴缩小子元素。flexShrink 与 flexGrow 非常相似,可以将溢出的尺寸视为负的剩余空间来理解。这两个属性协同工作,允许子元素根据需要增长或缩小。flexShrink 接受任何大于或等于 0 的浮点值,默认值为 0(在 Web 上,默认值为 1)。容器将根据子元素的 flexShrink 值加权缩小子元素。
你可以在此查看更多内容。 TypeScript JavaScript
Row Gap, Column Gap and Gap
* rowGap 设置元素行之间间隙(gutter)的大小。 * columnGap 设置元素列之间间隙(gutter)的大小。 * gap 设置行和列之间间隙(gutter)的大小。它是 rowGap 和 columnGap 的简写。
你可以将 flexWrap、alignContent 与 gap 结合使用,在项之间添加一致的间距。Gap 属性接受数值(点)或百分比字符串(例如在新架构上的 '10%')。
TypeScript JavaScript
Width and Height width 属性指定元素内容区域的宽度。同样,height 属性指定元素内容区域的高度。
width 和 height 都可以取以下值:
* auto (默认值):React Native 根据内容计算元素的宽度/高度,无论内容是其他子元素、文本还是图像。 * pixels:以绝对像素定义宽度/高度。根据组件上设置的其他样式,这可能不一定是节点的最终尺寸。 * percentage:分别定义宽度或高度为父元素宽度或高度的百分比。
TypeScript JavaScript
Position 元素的 position 类型定义了它是相对于自身、父元素还是包含块进行定位的。
* relative (默认值):默认情况下,元素进行相对定位。这意味着元素根据布局正常流进行定位,然后根据 top、right、bottom 和 left 的值相对于该位置进行偏移。偏移不会影响任何兄弟或父元素的位置。 * absolute:绝对定位的元素不参与正常布局流。相反,它独立于其兄弟元素进行布局。位置由 top、right、bottom 和 left 值决定。这些值将相对于其包含块定位元素。 * static:静态定位的元素根据布局正常流进行定位,并忽略 top、right、bottom 和 left 值。此位置还会导致元素不为绝对定位后代形成包含块,除非存在其他覆盖样式的属性(例如 transform)。这允许绝对定位的元素定位到非父元素的目标上。注意 static 仅在新架构上可用。
TypeScript JavaScript
包含块 元素的包含块是控制其位置和尺寸的祖先元素。
React Native 中包含块的工作方式与 Web 非常相似,但由于缺少某些 Web 特性,进行了一些简化。
绝对定位元素的 top、right、bottom 和 left 值是相对于其包含块的。
应用于绝对定位元素的百分比长度(例如 width: '50%' 或 padding: '10%')将根据包含块的尺寸计算。例如,如果包含块宽 100 点,则绝对定位元素的 width: 50% 会使其宽度为 50 点。
以下列表有助于确定给定元素的包含块:
如果该元素的 position 类型为 relative 或 static,则其包含块是其父元素。 如果该元素的 position 类型为 absolute,则其包含块是最近的满足以下任一条件的祖先元素: * 其 position 类型不是 static * 具有 transform
深入探索 查看交互式 yoga playground,以更好地理解 flexbox。 我们涵盖了基础知识,但布局可能需要许多其他样式。控制布局的完整 props 列表已在此处记录。 此外,你还可以查看来自 Wix 工程师的一些示例。