react native学习笔记4——FlexBox布局
FlexBoxReact Native是采用FlexBox(弹性)布局,使用FlexBox规则来指定某个组件的子元素的布局,FlexBox提供了在不同尺寸设备上都能保持一致的布局方式,它是CSS3弹性框布局规范,因此熟悉前端的同学可能对此感到很亲切,不过React Native的FlexBox与web上的CSS也存在少许差异。
FlexBox类似android开发中的LinearLayout(线性布局),不过还是有许多不同之处,千万不能用LinearLayout的知识生搬硬套。 在学习FlexBox属性之前,让我们先了解一个概念:主轴和次轴
父视图属性(容器属性)
flexDirectionflexDirection指定布局的主轴方向,定义了父视图中的子元素子元素是应该沿着水平轴(row)方向排列,还是沿着竖直轴(column)方向排列。如果未指定,默认值是竖直轴(column)方向。(这点与css中不同,但与android的LinearLayout是一致的,默认竖直方向排列)
代码示例: import React,{Component} from 'react';
import {
Text,View,StyleSheet
} from 'react-native';
export default class FlexDirectionDemo extends Component {
render() {
return (
<View style={Styles.container}> <Text style={Styles.subtitle}>flexDirectionDemo:row</Text> <View style={Styles.box1}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item}>4</Text> </View> <Text style={Styles.subtitle}>flexDirectionDemo:row-reverse</Text> <View style={Styles.box2}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item}>4</Text> </View> <Text style={Styles.subtitle}>flexDirectionDemo:column</Text> <View style={Styles.box3}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item}>4</Text> </View> <Text style={Styles.subtitle}>flexDirectionDemo:column-reverse</Text> <View style={Styles.box4}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item}>4</Text> </View> </View> ); } } const Styles = StyleSheet.create({ container: { backgroundColor: "#ffffff",flex: 1,},subtitle:{ backgroundColor: '#ffffff',alignItems: 'center' },box1:{ height: 60,backgroundColor: '#333333',flexDirection:"row",box2:{ height: 60,flexDirection:"row-reverse",box3:{ height: 180,flexDirection:"column",box4:{ height: 180,flexDirection:"column-reverse",item: { backgroundColor: "#f0f",width:30,margin: 4,height: 30,})
flexWrapflexWrap定义了子元素在父视图内是否允许多行排列,默认为nowrap(不换行)
代码示例: import React,StyleSheet
} from 'react-native';
export default class FlexWrapDemo extends Component {
render() {
return (
<View style={Styles.container}> <Text style={Styles.subtitle}>flexWrap:nowrap</Text> <View style={Styles.box1}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item}>4</Text> </View> <Text style={Styles.subtitle}>flexWrap:wrap</Text> <View style={Styles.box2}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item}>4</Text> </View> </View> ); } } const Styles = StyleSheet.create({ container: { backgroundColor: "#ffffff",box1:{ height: 150,flexWrap:"nowrap",box2:{ height: 150,flexWrap:"wrap",width:100,height: 50,})
justifyContentjustifyContent定义了子元素在主轴上的对齐方式。
import React,StyleSheet
} from 'react-native';
export default class JustifyContentDemo extends Component {
render() {
return (
<View style={Styles.container}> <Text style={Styles.subtitle}>JustifyContent:flex-start</Text> <View style={Styles.box1}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> </View> <Text style={Styles.subtitle}>JustifyContent:flex-end</Text> <View style={Styles.box2}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> </View> <Text style={Styles.subtitle}>JustifyContent:center</Text> <View style={Styles.box3}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> </View> <Text style={Styles.subtitle}>JustifyContent:space-between</Text> <View style={Styles.box4}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> </View> <Text style={Styles.subtitle}>JustifyContent:space-around</Text> <View style={Styles.box5}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> </View> </View> ); } } const Styles = StyleSheet.create({ container: { backgroundColor: "#0ff",box1:{ height: 100,justifyContent:"flex-start",box2:{ height: 100,justifyContent:"flex-end",box3:{ height: 100,justifyContent:"center",box4:{ height: 100,justifyContent:"space-between",box5:{ height: 100,justifyContent:"space-around",width:50,})
alignItemsalignItems定义子元素在次轴(与主轴垂直的轴)上的对齐方式。
import React,StyleSheet
} from 'react-native';
export default class AlignItemsDemo extends Component {
render() {
return (
<View style={Styles.container}> <Text style={Styles.subtitle}>alignItems</Text> <View style={Styles.box}> <Text style={Styles.item}>1</Text> <Text style={Styles.item}>2</Text> <Text style={Styles.item}>3</Text> <Text style={Styles.item_flex_end}>4</Text> <Text style={Styles.item}>5</Text> </View> </View> ); } } const Styles = StyleSheet.create({ container: { backgroundColor: "#0ff",height: 300,box:{ flex: 1,alignItems:"flex-end",//通过设置flex-start | flex-end | center | stretch;各种值可以看看效果 },flexGrow: 1,height: 100,item_flex_end: { backgroundColor: "#f0f",alignSelf: "flex-end",} })
子视图属性
alignSelfalignSelf属性以属性定义了flex容器内被选中子元素的对齐方式。允许该子元素有与其他子元素不一样的对齐方式,可覆盖alignItems 属性。
该属性可能取5个值,除了auto,其他都与alignItems属性完全一致。 以下图为例,该图中父元素的alignItems属性为flex-start,所以子元素按照 代码示例: import React,StyleSheet
} from 'react-native';
export default class AlignSelfDemo extends Component {
render() {
return (
<View style={AlignSelfDemoStyle.container}> <Text style={AlignSelfDemoStyle.subtitle}>alignSelf</Text> <View style={AlignSelfDemoStyle.box}> <Text style={AlignSelfDemoStyle.item}>1</Text> <Text style={AlignSelfDemoStyle.item}>2</Text> <Text style={AlignSelfDemoStyle.item}>3</Text> <Text style={AlignSelfDemoStyle.item_flex_end}>4</Text> <Text style={AlignSelfDemoStyle.item}>5</Text> </View> </View> ); } } const AlignSelfDemoStyle = StyleSheet.create({ container: { backgroundColor: "#0ff",} })
flexflex 属性定义了一个可伸缩元素的能力(flex的属性值大于0的时候才可伸缩)。
如果父元素只有一个子元素设置 flex的值,通常flex:1, 指定该子元素扩展以充满所有剩余空间。 import React,} from 'react-native';
export default class FlexDemo extends Component {
render() {
return (
<View style={ {flexDirection:'row',height:40,backgroundColor:"darkgray"}}> <View style={ {flex:1,backgroundColor:"red"}}> <Text style={ {fontSize:16}}>flex:1</Text> </View> <View style={ {flex:2,backgroundColor:"blue"}}> <Text style={ {fontSize:16}}>flex:2</Text> </View> <View style={ {flex:3,backgroundColor:"green"}}> <Text style={ {fontSize:16}}>flex:3</Text> </View> </View> ); } }
如果将三个子元素的flex都改为1,则三个子元素所占空间大小也是1:1:1 定位positionposition 属性设置元素的定位方式,为将要定位的元素定义定位规则。
绝对定位和相对定位。
如果你之前是做Android开发的,这里会感觉很不适应,这个absolute和relative与Android中的AbsoluteLayout和RelativeLayout大不相同,特别是relative,可以说是完全不同。 网上有很多人总结说“react native 相对定位不是相对于父容器,而是相对于兄弟节点”,我觉得说得很不准确。一个元素如果不设定position去定位的话,默认会形成文档流。每个元素会按顺序出现在文档流中,排到自己的位置上。而如果该元素设置了相对定位position:’relative’,则会相对于自己原本该在文档流的位置进行偏移,并且不影响其相邻的元素的位置摆放。因此总结下来,react native 相对定位不是相对于父容器,也不是相对于兄弟节点,而是相对于自己在文档流中正常位置进行定位。 绝对定位absolute则是相对于父容器进行绝对定位,脱离了文档流。 举个例子,有三个view,普通排列,由于rn是默认flexbox布局,所以会是从上到下一个挨着一个排列: import React,ScrollView,StyleSheet
} from 'react-native';
export default class PositionDemo extends Component {
render() {
return (
<ScrollView> <View style={{flex:1}}> <Text>FlexBox布局</Text> <View style={styles.container}> <View style={styles.box1}/> <View style={[styles.box2]}/> <View style={[styles.box3]}/> </View> <Text>第二个元素position=relative,top:20,left20</Text> <View style={styles.container}> <View style={styles.box1}/> <View style={[styles.box2,{position:'relative',top:20,left:20}]}></View> <View style={styles.box3}/> </View> <Text>第二个元素position=absolute,{position:'absolute',left:20}]}></View> <View style={styles.box3}/> </View> </View> </ScrollView> ); } } const styles = StyleSheet.create({ container: { height: 180,backgroundColor: '#CCCCCC',marginBottom: 10,box1: { width: 50,backgroundColor: '#FF0000' },box2: { width: 50,backgroundColor: '#00FF00' },box3: { width: 50,backgroundColor: '#0000FF' } });
好奇的朋友可以在第一组中为第二个元素设置一下 <View style={[styles.box2,{top:20,left:20}]}/>
看看会出现什么样的结果呢? 如上图,它与第二组的情况一样,所以我们可以看出元素默认的position是relative。即我们如果不设值position的话,默认按相对定位来处理。 其他属性margin 外边距 marginBottom 底部外边距 marginLeft 左外边距 marginRight 右外边距 marginTop 上外边距 marginVertical 上下外边距,如果marginTop与marginBottom一样的话,可以直接用这个值代替 marginHorizontal 左右外边距 borderColor 整体边框颜色 borderRadius 整体边框的圆角 borderWidth 整体边框的宽 borderStyle 边框样式 dotted solid double dashed等 borderBottomColor 底边框颜色 borderBottomWidth 底边框宽度 borderLeftColor 左边框颜色 borderLeftWidth 左边框宽度 borderRightColor 右边框颜色 borderRightWidth 右边框宽度 borderTopColor 上边框颜色 borderTopWidth 上边框宽度 borderBottomLeftRadius 左下角圆角边框 borderBottomRightRadius 右下角圆角边框 borderTopLeftRadius 上边框左圆角 borderTopRightRadius 上边框右圆角 padding 内边距 paddingBottom 底部内边距 paddingTop 顶部内边距 paddingLeft 左内边距 paddingRight 右内边距 paddingHorizontal 左右内边距 paddingVertical 上下内边距 height 元素高度,包含padding与border width 元素宽度,包含padding与border Demo本文的示例代码在: 下一篇将介绍布局实战篇 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |