本文只是简单地介绍下在React-Native中,使用CSS的Flex布局方式,完成RN中的控件布局,掌握这个布局方式对于后续开发有非常大的用途。
什么是Flexbox
Flexbox(Flexible Box)旨在提供一个更加有效的方式制定、调整和分布一个容器里的项目布局,即使他们的大小是未知或者是动态的。Flex布局主要思想是让容器有能力让其子项目能够改变其宽度、高度(甚至顺序),以最佳方式填充可用空间(主要是为了适应所有类型的显示设备和屏幕大小)。Flex容器会使子项目(伸缩项目)扩展来填满可用空间,或缩小他们以防止溢出容器。
与CSS的主要差异
React Native中的Flexbox的工作原理和web上的CSS基本一致,当然也存在少许差异。首先是默认值不同:
flexDirection
的默认值是column
而不是row
,alignItems
的默认值是stretch
而不是flex-start
,以及flex
只能指定一个数字值。
基本要素
因为Flexbox是整个模块,不是一个属性,它涉及很多东西,包括其整个组属性。他们当中一部分是容器(父元素,称为“伸缩容器”),另一部分是子元素(称为“伸缩项目”)。常规布局是基于块和内联流方向,而Flex布局是基于flex-flow流。请看看来自w3c规范中的这张图,解释了flex布局的主要思想。
属性
- 父容器的属性
- flexDirection: row | row-reverse | column(默认) | column-reverse 表明容器里面的子元素的排列方向。
- flexWrap: nowrap(默认) | wrap | wrap-reverse 如果子元素溢出父容器的时候是否进行换行。
- justifyContent: flex-start | flex-end | center | space-between | space-around; 这一个容器子元素横向排版在容器的哪个位置
- alignItems: flex-start | flex-end | center | baseline | stretch; 这个容器子元素纵向排版在容器的哪个位置
- 子容器的属性
- alignSelf: auto | flex-start | flex-end | center | stretch; 特定某个子元素的排布情况;
- position: relative(默认)| absolute;相比较Android由父视图决定布局的规则来说,React-Native是由子视图决定布局方式的
例子
-
flexDirection
:
export default class LearnFlexBox extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.sub} backgroundColor='#333333'/>
<View style={styles.sub} backgroundColor='#FF0000'/>
<View style={styles.sub} backgroundColor='#00FF00'/>
<View style={styles.sub} backgroundColor='#0000FF'/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'column', // row
height: 400,
},
sub: {
flex: 1,
height: 50,
}
});
-
alignItems
:
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
height: 400,
alignItems: 'stretch', // flex-start, flex-end, center, stretch, 当设置为stretch时,子容器的height属性不能设置
},
sub: {
flex: 1,
// height: 50,
}
});
-
justifyContent
,有垂直就有水平:
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
height: 400,
justifyContent: 'flex-start', // flex-start, flex-end, center, space-between, space-around
},
sub: {
height: 300,
width: 50,
}
});
-
alignSelf
:
export default class LearnFlexBox extends Component {
render() {
return (
<View style={styles.container}>
<View style={styles.sub1} backgroundColor='#333333'/>
<View style={styles.sub2} backgroundColor='#FF0000'/>
<View style={styles.sub3} backgroundColor='#00FF00'/>
<View style={styles.sub4} backgroundColor='#0000FF'/>
<View style={styles.sub5} backgroundColor='#ABCDEF'/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
height: 600,
},
sub1: {
flex: 1,
alignSelf: 'stretch', // auto, flex-start, flex-end, center, stretch
},
sub2: {
flex: 1,
height: 300,
alignSelf: 'flex-start',
},
sub3: {
flex: 1,
height: 300,
alignSelf: 'flex-end',
},
sub4: {
flex: 1,
height: 300,
alignSelf: 'center',
},
sub5: {
flex: 1,
height: 300,
alignSelf: 'auto',
}
});
-
flex
,主要控制子容器在父容器中的占比,如图:
sub1: {
flex: 1,
alignSelf: 'stretch', // auto, flex-start, flex-end, center, stretch
},
sub2: {
flex: 2,
height: 300,
alignSelf: 'flex-start',
},
sub3: {
flex: 3,
height: 300,
alignSelf: 'flex-end',
},
sub4: {
flex: 4,
height: 300,
alignSelf: 'center',
},
sub5: {
flex: 5,
height: 300,
alignSelf: 'auto',
}
-
position
,主要控制子视图的布局方式,如图: -
relative
布局:
sub6: {
position: 'relative',
height: 100,
width: 100
}
```
sub6: {
position: 'relative',
left: 10,
height: 100,
width: 100
},
```
注:以上两种`relative`的不同之处在于后者比前者多了一句`left: 10`这个布局,导致了`sub6`的涂层位置直接跟`sub1`黑色的图层处于同一层级了,并不像前者那样是在整个图层的最外层,因此我们得出的结论是:
当postion键的值为`relative`时,不可以使用`bottom`和`right`键继续描述位置,`top`和`left`键表示当前组件距离上一个同级组件最上(左)沿有多少pt
-
absolute
布局:
sub7: {
position: 'absolute',
left: -90,
height: 100,
width: 100
}
```
sub7: {
position: 'absolute',
left: 10,
height: 100,
width: 100
}
```
```
sub7: {
position: 'absolute',
left: 80,
height: 100,
width: 100
}
```
```
sub7: {
position: 'absolute',
left: 200,
height: 100,
width: 100
}
```
注:以上四种`absolute`的不同之处在于`left: xxx`这个布局的值不一样,导致了`sub7`的涂层位置在不断变化,仔细观察我们得出的结论是:
使用`absolute`布局子视图时,子视图所处的图层 = 该子视图是否有“接触”的父视图的层级 + 1
参考资料
一个完整的Flexbox指南
3分钟轻松玩转React Native中position、flexbox布局
A Complete Guide to Flexbox
React Native 之 flexbox 布局详解篇
React-Native中文网