React Native 样式表:{flex:1} 做什么?

React Native Stylesheet: what does {flex:1} do?

React Native 使用 flexbox 进行布局。在我见过的所有例子中,他们都是这样做的:

var styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row'
  }
});

我对 flex: 1 部分很好奇。根据 Chris Coyier 在这里的定义 https://css-tricks.com/snippets/css/a-guide-to-flexbox/flex: 1 应该与 flex-grow: 1 相同,但对我来说 React Native 中的 flex: 1 等同于 display: flex在 CSS.

这是一个 CodePen,它演示了 flex: 1 React Native 示例使用它的方式在 CSS:

中没有做任何事情

http://codepen.io/johnnyo/pen/BoKbpb

直到我们在CSS中使用display: flex,flexbox才开始工作:

http://codepen.io/johnnyo/pen/epZXgz

那么这是否意味着 React Native 中的 flex: 1 等同于 CSS 中的 display: flex

cssflexbox和Facebook实现的flexbox有很大的不同。有很多共同点,但默认值却大不相同。具体来说:

Everything is display: flex by default. All the behaviors of block and inline-block can be expressed in term of flex but not the opposite.

flex: 属性仅在同一层级中很少有具有不同 flex 值的组件时使用(flex: 1, flex: 3)意味着第二个元素应该比第一个元素大 3 倍。 flex 属性是唯一受支持的属性(不支持 grow/shrink)。

更多信息:https://github.com/facebook/css-layout

对 Jarek Potiuk 的回答的评论:'flex: 1' 确实在 react-native 中做了一些类似于 flex-grow 的行为。即使它是唯一具有 flex: defined 的。

flexDirection、alignItems、justifyContent等样式都定义了元素children的样式。类似于CSS Display: flex,也定义了children。

相比之下,flex:x 定义了元素本身。

例如如果容器组件有 flexDirection: 'row', alignItems: 'center'
还有 3 children:

child 1 has width 50

child 2 has flex 1 (or any other number, but 1 is common practice)

child 3 has width 50

然后中间的组件会'stretch'让3个children一起填满parent组件的整个宽度。

和你一样,我也很难理解这个没有正确记录在 Facebook 代码上的标签,但我最终发现它做了两件事:

  1. 容器将任何具有 flex 属性的子项视为高度为 0,以便确定它们占用了多少 space。
  2. 具有 flex: X 的组件展开以占用其他组件布置后其容器中剩余的任何空间。他们按 X 值的比例分享额外的 space。

第一项是为什么 flex: 1 看起来与 display: flex 具有相同的效果。考虑以下 JSX 代码:

<ExampleAppContainer>
    <Text>
        I get printed.
    </Text>
    <Text style={{flex: 1}}>
        But I don't :(
    </Text>
</ExampleAppContainer>

只有第一个文本组件被打印,因为第二个文本组件的高度被认为是 0。ExampleAppContainer 为第一个文本组件分配了足够的 space,但没有任何第二个有扩展空间。

现在考虑这段代码:

<ExampleAppContainer style={{flex:1}}>
    <Text>
        I get printed.
    </Text>
    <Text style={{flex: 1}}>
        And so do I!
    </Text>
</ExampleAppContainer>

由于 ExampleAppContainerflex: 1,它会扩展以占用尽可能多的空间。假设它是应用程序 React 部分的根组件,这通常会是整个 phone 屏幕。接下来,它为第一个文本组件分配足够的 space,并允许第二个文本组件展开,占据屏幕的其余部分。

以这种方式,您通常需要在组件层次结构中一直向下应用 flex: 1,以便让具有 flex: N 空间的最内层组件正常扩展。

很多教程都使用 flex: 1,就像您在示例中所做的一样。主要是因为有时候(视元素而定,比如默认是ListStyle,没记错的话)组件不会占满整个screen/area定义尺寸,例如高度(例如 height: '400px')。 Flex: 很棒,因为它可以让事物对各种尺寸保持响应。

但我应该注意,对于任何 没有同级 的组件,flex 的值完全是任意的。前任。对于您的顶级组件,您可以说 flex: 43254315,它的作用与 flex: 1 相同。它只是意味着 "take up the entire space"(无论 "entire" 可能是什么)。

另一方面,如果您有一些同级组件,那么 flex 值很重要。例如,如果一个组件是 flex: 2,另一个是 flex: 3,那么第一个占据屏幕的 2/5,第二个占据屏幕的 3/5。

简而言之:根据您的风格,它可能 看起来 就像 flex: 1display: flex 一样,但这只是因为您的风格在你的例子中使用它。如果你给它一些兄弟姐妹,你会发现它的行为非常不同。

这很简单,当你对任何元素说 flex: 1 时,如果这个元素有 flex: 1 并且没有父元素获取屏幕大小的所有高度,那么该元素获取父元素的所有高度。

例如你想要一个容器元素获取屏幕的所有高度,这个元素有三个子元素,每个元素有 1/3 的屏幕高度 对于此示例,只需获取父元素 flex: 1 和三个子元素 flex: 1/3 请参阅下面的代码

<View style={{flex: 1,backgroundColor: 'red'}}>

        <View style={{flex: 1/3, backgroundColor: 'green'}}></View>

        <View style={{flex: 1/3, backgroundColor: 'yellow'}}></View>

        <View style={{flex: 1/3, backgroundColor: 'pink'}}></View>

      </View>
flex: 1
  1. 告诉组件填充所有可用的 space(在具有相同父级的其他组件之间共享)。

  2. 如果存在具有 flex 值的同级组件,则它们的父组件需要具有 flex: 1(或更高)。如果父项没有固定的宽度和高度或弹性,则父项的尺寸将为 0,并且弹性子项将不可见。