今天是重阳节,祝大家节日快乐,今天继续更新RN相关的博客。上篇博客《ReactNative之从HelloWorld中看环境搭建、组件封装、Props及State》中我们通过一个HelloWorld的一个示例介绍了RN的环境搭建、组件封装、Props以及States。经过这么多天,今天我们继续来看RN的东西,本篇博客是关于RN的Flex布局的,也就是说是关于RN中控件放哪儿的一篇博客。在RN中使用的是Flex布局,如果你之前接触过Web前端的话对FlexBox布局并不陌生,但是如果你之前没做过Web开发的话,也不影响看今天的博客。本篇博客也是RN开发的基础,算是比较重要的。
RN中控件的布局方式与Web前端开发中的div+css的盒式布局是极为相似的。本篇博客就来详细的讲解一下RN中的FlexBox布局,中文名“弹性布局”。RN中的FlexBox布局和CSS中的FlexBox大体相同,也是通过一些属性来控制控件的位置、大小以及各个控件之间的关系。在FlexBox中分为 容器属性(flexDirection、flexWrap、alignItems、justifyContent、alignContent)和 元素属性(flex、alignSelf、margin、padding、border、width、height等等)。顾名思义,容器属性是用来添加到 父组件上来控制子组件的位置的属性,而 元素属性则是添加到子组件本身控制本身的一种属性。稍后会详细介绍。
接下来我们将根据具代码来详细的介绍常用的几种FlexBox布局的属性,。根据常用性,下方会依次介绍RN中的Flex布局中的flex、flexDirection、justifyContent、alignContent、flexWrap、AlignItem、AlignSelf这些常用的属性。本篇博客所涉及的Demo会上传到博客最后方的github链接中。
先入为主,下方这个gif中所有的内容就是我们今天要结束的东西,全是关于Flex布局的。
一、Flex
首先我们先来看一下flex的使用方式,flex属性接收的是一个number类型的值, 该值表示弹性布局的比例系数。具体的我们还要看一下下方关于Flex的一个Demo。
下方就是flex的具体使用方式,其中的flexValue是一个number类型的值。
<View style={{ flex: flexValue />
接下来我们来看一下flex具体的一个示例。我们通过点击来修改中间的flex的值来观察flex对每个view的影响:
-
三个黑块中的初始的flex值为1, 所以三个黑色方块会平分屏幕。
-
每点击一次,中间的黑块的flex数增加1,然后我们就看到中间黑块会增大,三个黑块的比例变成了1 : 2 : 1。每次点击都会有变化。
最后我们来简单的看一下该效果的实现,代码如下。
-
首先我们来看一下item的实现,Item即对应着每个黑块。这个item方法有个名为flexValue的参数,该参数用来接收设置的flex的值。所以在item中我们将flexValue指定给了View的flex属性。
-
然后我们在看一下render中的实现。在Render中,我们添加了一个View来容纳item(黑块),View中三个item就对应着上述的三个黑块。中间的item的flex的值是从Status中获取的,下方会介绍到。
-
最后我们在看一个ClickView这个方法,该方法会在点击View时执行,执行该方法时,我们为Status存储的flexValue自增了1。也就是说没点击 1 次中间的item的flex就会增加1。所以我们最终看到的效果是没点击一次,中间的黑块会增大。
下方是上述示例的完整代码:
1 // flex 2 import { Component } from "react"; 3 import { TouchableOpacity, View, Text } from "react-native"; 4 import React from "react"; 5 6 type FlexStateType = { 7 flexValue: number 8 } 9 export default class FlexTestComponent extends Component<null, FlexStateType> { 10 flexValue = 1; 11 constructor(props) { 12 super(props); 13 this.state = { 14 flexValue: this.flexValue 15 }; 16 } 17 18 clickView = () => { 19 this.flexValue ++; 20 this.setState({flexValue: this.flexValue}) 21 }; 22 23 item = (flexValue: number) => { 24 return ( 25 <View style={{ flex: flexValue, height: 50, backgroundColor: 'black', marginLeft:10, marginRight: 10 , justifyContent: 'center', alignItems:'center'}}> 26 <Text style = {{color: '#fff'}}>flex = {flexValue}</Text> 27 </View> 28 ); 29 }; 30 31 render () { 32 const { 33 flexValue 34 } = this.state; 35 return ( 36 <TouchableOpacity onPress={this.clickView}> 37 <View style={{ height: 60, '100%', backgroundColor: '#e5e5e5', flexDirection: 'row' , alignItems: 'center'}}> 38 {this.item(1)} 39 {this.item(flexValue)} 40 {this.item(1)} 41 </View> 42 </TouchableOpacity> 43 ); 44 } 45 }
二、FlexDirection
看完flex属性,接下来我们来看一下flexDirection属性。该属性在FlexBox布局中也是一个尤为重要而且比较常用的一个属性。flexDirection主要是用来控制子元素的布局方向的,主要分为横向布局和纵向布局,默认是纵向布局(column)。下方是flexDirection的属性值和使用方式。
属性值:
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse";用法示例:
<View style={{ flexDirection: 'row' />
flexDirection的属性值主要有以下几个:
-
row : '行',该值表示子元素自左向右横向排列, 。如下图的row, 先放的子元素1,如果有子元素2的话,会放到子元素1的右边,依次类推的横向布局。
-
row-reverse: '逆向的行',这个与row相反,该属性表示自右向左横向排列。具体参见下图中的row-reverse。
-
column:'列',该属性值表示子元素自上而下纵向排列,具体参见下方的column。
-
column-reverse: '逆向的列',这个与column相反,该属性则表示自下而上的纵向排列,具体参见下方的column-reverse。
因该部分的demo对应的代码比较简单,介绍如下:
-
首先我们封装了一个名为FlexDirectionTestView的视图,该视图对应着上述展示 1 2 3的视图。该视图对外留了一个属性,用来接收flexDirection。外边传入什么flexDirection的值,1 2 3这三个子视图就按什么排列。
-
在FlexDirectionTestComponent组件中,我们就调用了FlexDirectionTestView这个视图,传入了不同的flexDirection属性,从而这个 1 2 3 子元素就会按照我们要求的样式去展示。
完整代码示例:
1 // flexDirection 2 import React, { Component } from 'react' 3 import { FlexStyle, StyleSheet, Text, View } from 'react-native' 4 5 export default function FlexDirectionTestComponent () { 6 return ( 7 <View style={{ height: 180, backgroundColor: '#c1c1c1' , flexDirection: 'row'}}> 8 <View style={{ height: '100%', '50%', justifyContent: 'space-around'}}> 9 <FlexDirectionTestView value={{ flexDirection: 'row' }}/> 10 <FlexDirectionTestView value={{ flexDirection: 'row-reverse' }}/> 11 </View> 12 13 <View style={{ height: '100%', '50%', flexDirection: 'row' , justifyContent: 'space-around'}}> 14 <FlexDirectionTestView value={{ flexDirection: 'column' }}/> 15 <FlexDirectionTestView value={{ flexDirection: 'column-reverse' }}/> 16 </View> 17 </View> 18 ) 19 } 20 21 type FlexDirectionProps = { 22 value?: FlexStyle 23 } 24 25 class FlexDirectionTestView extends Component<FlexDirectionProps> { 26 render () { 27 return ( 28 <View style={[myStyle.flexDirectionProps, { flexDirection: this.props.value.flexDirection }]}> 29 <SubView value={'1'}/> 30 <SubView value={'2'}/> 31 <SubView value={'3'}/> 32 </View> 33 ) 34 } 35 } 36 37 type SubViewProps = { 38 value: string 39 } 40 class SubView extends Component<SubViewProps> { 41 render () { 42 return( 43 <View style={myStyle.subViewStyle}> 44 <Text style={{ color: 'white', fontSize: 17 }}> {this.props.value} </Text> 45 </View> 46 ) 47 } 48 } 49 50 const myStyle = StyleSheet.create({ 51 subViewStyle: { 52 margin: 10, 53 borderRadius: 25, 54 25, 55 height: 25, 56 backgroundColor: 'red', 57 justifyContent: 'center', 58 alignItems: 'center' 59 }, 60 flexDirectionProps: { 61 backgroundColor: 'gray', 62 margin: 5 63 } 64 });
三、JustifyContent
今天这篇博客的干货还是比较足的,接下来我们来看一下第三个比较重要的属性justifyContent。该属性也是比较常用的,通常被用来控制子元素的左右方向的布局,这个与上面的flexDirection不同,justifyContent会控制整体子元素左右方向上的一个约束关系。下方是justifyContent的属性值和使用方式
属性值:
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly"用法示例:
<View style={{ justifyContent: 'flex-start' />
具体的还得看下方这个GIF图,该图中就列举了justifyContent所有的属性值,并且展示了每个属性值的不同表现形式,接下来详细的介绍一下每个属性值的作用。
-
flex-start: 该属性值的功能是让所有子元素靠左对齐,如下方点击flex-start的布局形式。
-
center: 则表示子元素在左右方向上居中展示,如下方点击Center按钮对应的布局形式。
-
flex-end: 这个与flex-start相反,flex-end则表示子元素靠右对齐,对应着下方点击flex-end按钮的布局形式。
-
space-between:从字面意思上不难看出,该属性值对应的是左右间距平分于子元素中间的布局方式,设置该属性值后,左右边上是子元素是紧贴父View的左右边距的,间距平分与子元素中间。
-
space-around: 该属性也是比较好理解的,就是左右间距环绕在子元素周围,从下方点击space-around的效果不难看出,设置该属性后,每个元素的左右边距是一致的,环绕在子元素之间。
-
space-evenly: 该属性值的意思是子元素的左右间距均分,这个间距包括子元素与子元素的间距,还包括子元素与父元素的间距。
介绍完上述属性,我们来简单的看一下该示例的实现代码,从上述操作来看本部分的Demo会相对复杂一些。首先来看一下上述按钮区域对应的代码片段:
-
首先我们定义了一个OperaView来容纳所有的点击的View,在该View中调用了我们自定义的customButton组件。
-
customButton组件接收一个参数,这个参数对应的就是justifyContent的属性值。每次点击该按钮,就会把按钮对应的属性值写入Status中。
-
方法ClickView即为CustomButton点击时对应执行的方法。
看完按钮区域的代码,接下来我们就来看一下布局区域的代码:
-
首先来看一下Item,下方的item函数返回的就是布局区域的每个方框,每个方框的高度相同,宽度由参数决定。
-
然后在看一下resultDisplayView, 该View函数对应的就是按钮下方的布局区域,该View的JustifyContent属性的值是直接从state中获取的。
-
最后就来看一下render中了,在render中分别调用了按钮区和布局区两块的内容。
完整代码如下:
1 // justifyContent 2 import { Component } from "react"; 3 import { Text, TouchableOpacity, View } from "react-native"; 4 import React from "react"; 5 6 type JustifyContentType = "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly"; 7 type JustifyContentCompontStateType = { 8 justifyContentValue: JustifyContentType 9 } 10 export default class JustifyContentTestComponent extends Component<null, JustifyContentCompontStateType> { 11 constructor(props) { 12 super(props); 13 this.state = { 14 justifyContentValue: 'flex-start' 15 }; 16 } 17 18 clickView = (value: JustifyContentType) => () => { 19 this.setState({ justifyContentValue: value}); 20 }; 21 22 customButton = (title: JustifyContentType) => { 23 return ( 24 <TouchableOpacity onPress={this.clickView(title)}> 25 <View style = {{ 120, height: 30, backgroundColor: 'green', margin: 5, justifyContent:'center', alignItems:'center'}}> 26 <Text style={{color: '#fff', fontSize: 17}}>{title}</Text> 27 </View> 28 </TouchableOpacity> 29 ); 30 }; 31 32 operaView = () => { 33 return ( 34 <View style={{ 35 height: 90, 36 '100%', 37 justifyContent: 'center', 38 alignItems: 'center', 39 flexDirection:'row', 40 flexWrap:'wrap'}}> 41 {this.customButton('flex-start')} 42 {this.customButton('flex-end')} 43 {this.customButton('center')} 44 {this.customButton('space-between')} 45 {this.customButton('space-around')} 46 {this.customButton('space-evenly')} 47 </View> 48 ); 49 }; 50 51 item = ( number) => { 52 return ( 53 <View style = {{ height: 30, width, backgroundColor: 'green' , margin: 2}}/> 54 ); 55 }; 56 57 resultDisplayView = () => { 58 const { 59 justifyContentValue 60 } = this.state; 61 return ( 62 <View style={{ height: 110, '100%', justifyContent: justifyContentValue, flexDirection: 'row', flexWrap:'wrap' }}> 63 {this.item(60)} 64 {this.item(100)} 65 {this.item(30)} 66 {this.item(80)} 67 {this.item(100)} 68 {this.item(90)} 69 {this.item(30)} 70 {this.item(80)} 71 </View> 72 ); 73 }; 74 75 render () { 76 return ( 77 <View style={{ height: 200, backgroundColor: '#e5e5e5' }}> 78 {this.operaView()} 79 {this.resultDisplayView()} 80 </View> 81 ); 82 } 83 }
四、AlignContent
接下来来看一下AlignContent这个属性及其相关的属性值。该属性与上面的JustifyContent属性的功能差不多,JustifyContent负责左右方向的子元素之间的关系,而AlignContent则负责上下方向上的子元素之间的布局。下方是AlignContent的相关属性值和使用方式:
属性值:
alignContent?:"flex-start" | "flex-end" | "center" | "stretch" | "space-between" | "space-around"用法示例:
<View style={{ alignContent: 'flex-start' />
按照上述的思路,我们还是通过一个Demo来看一下每个属性值的具体的作用。下方就是本部分对应的Demo,每个按钮对应着AlignContent的一个属性值,点击相关按钮后,下方的子元素就会按照点击的按钮进行设置。下方是具体介绍:
-
flex-start: 子元素顶部对齐,点击下方的flex-start按钮会看到所有子元素向上对齐了。
-
center: 上下方向上居中,也就是说设置该属性,子元素会在上下方向上进行居中展示。
-
flex-end: 该属性与flex-start相反, 设置该属性,子元素会位于父元素的底部展示。
-
space-between:间隔填充,子元素的上下间距位于子元素中间。
-
space-around: 即间隔环绕在子元素的上下,与JustifyContent的space-around类似。
-
stretch:拉伸,该属性只有在子元素的高度没有设置的情况下适用,该情况下会自适应高度,以至填满父视图,具体如下所示:
代码和之前的Demo的实现思路差不多,在此就不做过多赘述了,下方是该部分的完整示例:
1 // alignItem 2 import { FlexAlignType, Text, TouchableOpacity, View } from "react-native"; 3 import { Component } from "react"; 4 import React from "react"; 5 6 type AlignContentType = "flex-start" | "flex-end" | "center" | "stretch" | "space-between" | "space-around"; 7 8 type AlignContentTestCompontStateType = { 9 alignContentValue: AlignContentType 10 } 11 export default class AlignContentTestComponent extends Component<null, AlignContentTestCompontStateType> { 12 constructor(props) { 13 super(props); 14 this.state = { 15 alignContentValue: 'flex-start' 16 }; 17 } 18 19 clickView = (title: AlignContentType) => () => { 20 this.setState({ alignContentValue: title}); 21 }; 22 23 customButton = (title: AlignContentType) => { 24 return ( 25 <TouchableOpacity onPress={this.clickView(title)}> 26 <View style = {{ 120, height: 30, backgroundColor: 'green', margin: 5, justifyContent:'center', alignItems:'center'}}> 27 <Text style={{color: '#fff', fontSize: 17}}>{title}</Text> 28 </View> 29 </TouchableOpacity> 30 ); 31 }; 32 33 operaView = () => { 34 return ( 35 <View style={{ 36 height: '40%', 37 '100%', 38 justifyContent: 'center', 39 alignItems: 'center', 40 flexDirection:'row', 41 flexWrap:'wrap'}}> 42 {this.customButton('flex-start')} 43 {this.customButton('center')} 44 {this.customButton('flex-end')} 45 {this.customButton('space-between')} 46 {this.customButton('space-around')} 47 {this.customButton('stretch')} 48 </View> 49 ); 50 }; 51 52 item = ( number, height: number) => { 53 return ( 54 <View style = {{ height: height, width, backgroundColor: 'red' , margin: 2}}/> 55 ); 56 }; 57 58 resultDisplayView = () => { 59 const { 60 alignContentValue 61 } = this.state; 62 63 let height = 30; 64 if (alignContentValue === 'stretch') { 65 height = -1; 66 } 67 return ( 68 <View style={{ height: "60%", '100%', alignContent: alignContentValue, backgroundColor: '#efefef', flexDirection: 'row', flexWrap:'wrap'}}> 69 {this.item(50, height)} 70 {this.item(80, height)} 71 {this.item(30, height)} 72 {this.item(60, height)} 73 {this.item(50, height)} 74 {this.item(100, height)} 75 {this.item(30, height)} 76 {this.item(50, height)} 77 {this.item(80, height)} 78 {this.item(30, height)} 79 </View> 80 ); 81 }; 82 83 render () { 84 return ( 85 <View style={{ height: 200, backgroundColor: '#e5e5e5'}}> 86 {this.operaView()} 87 {this.resultDisplayView()} 88 </View> 89 ); 90 } 91 }
五、flexWrap
接下来看一下flexWrap这个属性,该属性负责折行的。例如当一个View没有设置flexWrap属性时,子元素又是横排的情况时,会在一行上一直往后排,并不会折行。如果想折行的话,那么就得使用这个flexWrap属性了,下方是flexWrap属性的相关值和用法:
属性值:
flexWrap?:"wrap" | "nowrap" | "wrap-reverse"
用法示例:
<View style={{ flexWrap: 'wrap' />
flexWrap的属性值比较少,也比较好理解,下方就进行简单的描述:
-
wrap: 折行,设置该属性意味着一行放不下时会自动换到下一行进行展示。
-
nowrap: 不这行,默认值,超出屏幕后也一直往一行后边叠加。
-
wrap-reverse: 逆向折行,这个虽然在查看类型的时候有这个选项,但是实测是不可用的,可忽略。
下方就是flexWrap所对应的Demo, 该Demo中的View就设置了flexWrap的属性为wrap的值,没点击一次我们就随机的往后边添加一个随机宽度的子View。从下方gif中不难看出,当最后一个View放不下时会自动的换到下一行进行展示。具体如下所示:
该示例的完整代码:
1 // flexWrap 2 import { Component } from "react"; 3 import { TouchableOpacity, View } from "react-native"; 4 import React from "react"; 5 6 type FlexWrapTestComponentStateType = { 7 allViews: Array<any> 8 } 9 export default class FlexWrapTestComponent extends Component<null, FlexWrapTestComponentStateType> { 10 constructor(props) { 11 super(props); 12 this.state = { 13 allViews : [this.item()] 14 }; 15 } 16 17 clickView = () => { 18 let items = this.state.allViews; 19 items.push(this.item()); 20 this.setState({allViews: items}); 21 }; 22 23 item = () => { 24 let randomWidth = Math.random() * 100 + 10; 25 return ( 26 <View style={{backgroundColor: 'green', height: 30, randomWidth, margin: 5}} /> 27 ); 28 }; 29 30 render () { 31 return ( 32 <TouchableOpacity onPress={this.clickView}> 33 <View style={{ height: 100, backgroundColor: '#eaeaea' , flexDirection: 'row', flexWrap: 'wrap',}}> 34 {this.state.allViews} 35 </View> 36 </TouchableOpacity> 37 ); 38 } 39 }
六、AlignItem
该属性也是比较常用的,用来定义子元素在交叉轴上的对齐方式。也就是说,子元素是横向排列的,那么该属性就约定纵轴方向上的对齐方式。AlignItem属性的属性值也没几个,也比较好理解,下方是AlignItem对应的熟悉值和使用方式:
属性值:
type FlexAlignType = "flex-start" | "flex-end" | "center" | "stretch" | "baseline";用法示例:
<View style={{ alignItem: 'flex-start' />
下方就是真的AlignItem实现的一个Demo, 我们将根据下方的Demo来具体的看一下AlignItem所对应的每个属性值的作用,具体如下所示:
-
flex-start: 首先还是来看一下flex-start, 下方我们的子元素是横向排列的,所以设置flex-start时,就意味着,子元素在纵轴开始的位置对齐,也就是顶部对齐。
-
center: 也是以横向排列的子元素为例,当设置alignItem为Center时,表示交叉轴方向上居中对齐,具体在该Demo中表现的是上下方向上居中对齐。
-
flex-end: 这个与flex-start相反,表示以交叉轴的尾部对齐。
-
baseline: 这个就比较有意思了,设置该属性值就意味着子元素以子元素中的文字的基线对齐。
该示例完整代码如下:
1 // alignItem 2 import { FlexAlignType, Text, TouchableOpacity, View } from "react-native"; 3 import { Component } from "react"; 4 import React from "react"; 5 6 type AlignItemTestCompontStateType = { 7 alignItemValue: FlexAlignType 8 } 9 export default class AlignItemTestComponent extends Component<null, AlignItemTestCompontStateType> { 10 constructor(props) { 11 super(props); 12 this.state = { 13 alignItemValue: 'flex-start' 14 }; 15 } 16 17 clickView = (title: FlexAlignType) => () => { 18 this.setState({ alignItemValue: title}); 19 }; 20 21 customButton = (title: FlexAlignType) => { 22 return ( 23 <TouchableOpacity onPress={this.clickView(title)}> 24 <View style = {{ 80, height: 30, backgroundColor: 'red', margin: 5, justifyContent:'center', alignItems:'center'}}> 25 <Text style={{color: '#fff', fontSize: 17}}>{title}</Text> 26 </View> 27 </TouchableOpacity> 28 ); 29 }; 30 31 operaView = () => { 32 return ( 33 <View style={{ height: '100%', '30%', backgroundColor: '#e0e0e0', justifyContent: 'center', alignItems: 'center' 34 }}> 35 {this.customButton('flex-start')} 36 {this.customButton('center')} 37 {this.customButton('flex-end')} 38 {this.customButton('stretch')} 39 {this.customButton('baseline')} 40 </View> 41 ); 42 }; 43 44 item = (height: number, fontSize: number) => { 45 return ( 46 <View style = {{ height: height, 50, backgroundColor: 'red' , margin: 10 }}> 47 <Text style={{fontSize: fontSize}}> {fontSize} </Text> 48 </View> 49 ); 50 }; 51 52 resultDisplayView = () => { 53 const { 54 alignItemValue 55 } = this.state; 56 57 let heights = [100, 150, 80]; 58 if (alignItemValue === 'stretch') { 59 heights = [-1, -1, -1]; 60 } 61 return ( 62 <View style={{ height: '100%', '70%', alignItems: alignItemValue, backgroundColor: '#efefef', flexDirection: 'row', justifyContent: 'center' }}> 63 {this.item(heights[0], 10)} 64 {this.item(heights[1], 20)} 65 {this.item(heights[2], 30)} 66 </View> 67 ); 68 }; 69 70 render () { 71 return ( 72 <View style={{ height: 200, backgroundColor: '#e5e5e5' , flexDirection: 'row'}}> 73 {this.operaView()} 74 {this.resultDisplayView()} 75 </View> 76 ); 77 } 78 }
七、AlignSelf
最后我们来看一下这个AlignSelf属性,该属性是元素属性,主要设置在子元素上,用来控制单个子元素在父元素的交叉轴的位置。AlignSelf的作用方式与AlignItem差不多,只不过一个作用于父元素,一个是作用于子元素。下方是AlignSelf的属性值和用法示例:
属性值:
type FlexAlignType = "flex-start" | "flex-end" | "center" | "stretch" | "baseline";type AlignSelfType = "auto" | FlexAlignType;用法示例:
<View/><View style={{ alignSelf: 'flex-start' /></View>
最后我们仍然通过一个Demo来看一下AlignSelf的表现形式。在下方Demo中我们依次为右边中间的黑块设置的AlignSelf属性。每个属性的值的意思可参见AlignItem的属性值,只不过这些属性值是作用于子元素的。具体关于AlignSelf的内容就不做过多赘述了。
该部分Demo完整示例:
1 // alignSelf 2 import { FlexAlignType, Text, TouchableOpacity, View } from "react-native"; 3 import { Component } from "react"; 4 import React from "react"; 5 6 type AlignSelfTestCompontStateType = { 7 alignItemValue: FlexAlignType 8 } 9 export default class AlignSelfTestComponent extends Component<null, AlignSelfTestCompontStateType> { 10 constructor(props) { 11 super(props); 12 this.state = { 13 alignItemValue: 'flex-start' 14 }; 15 } 16 17 clickView = (title: FlexAlignType) => () => { 18 this.setState({ alignItemValue: title}); 19 }; 20 21 customButton = (title: FlexAlignType) => { 22 return ( 23 <TouchableOpacity onPress={this.clickView(title)}> 24 <View style = {{ 80, height: 30, backgroundColor: 'black', margin: 5, justifyContent:'center', alignItems:'center'}}> 25 <Text style={{color: '#fff', fontSize: 17}}>{title}</Text> 26 </View> 27 </TouchableOpacity> 28 ); 29 }; 30 31 operaView = () => { 32 return ( 33 <View style={{ height: '100%', '30%', backgroundColor: '#e0e0e0', justifyContent: 'center', alignItems: 'center' 34 }}> 35 {this.customButton('flex-start')} 36 {this.customButton('center')} 37 {this.customButton('flex-end')} 38 {this.customButton('stretch')} 39 </View> 40 ); 41 }; 42 43 resultDisplayView = () => { 44 const { 45 alignItemValue 46 } = this.state; 47 48 let height = 80; 49 if (alignItemValue === 'stretch') { 50 height = -1 51 } 52 return ( 53 <View style={{ height: '100%', '70%', alignItems: 'flex-start', backgroundColor: '#efefef', flexDirection: 'row', justifyContent: 'center' }}> 54 <View style = {{ height: 150, 50, backgroundColor: 'black' , margin: 10}}/> 55 <View style = {{alignSelf: alignItemValue, height: height, 50, backgroundColor: 'black' , margin: 10}}/> 56 <View style = {{ height: 100, 50, backgroundColor: 'black' , margin: 10}}/> 57 </View> 58 ); 59 }; 60 61 render () { 62 return ( 63 <View style={{ height: 180, backgroundColor: '#e5e5e5' , flexDirection: 'row'}}> 64 {this.operaView()} 65 {this.resultDisplayView()} 66 </View> 67 ); 68 } 69 }
经过本篇博客的详细介绍想必对FlexBox有了更详细的了解,掌握了上述属性后,在RN中写布局应该就不是什么难事儿了。当然本篇博客值介绍了FlexBox布局比较核心的部分,想什么Margin、Padding等等这些属性比较简单,就不做过多赘述了。本篇博客所涉及的所有Demo会在github上给出,下方会给出相关链接。
下篇博客会集中根据具体示例来聊一下RN中常用的动画。