这段时间熟悉了一下ReactNative,里面的布局感觉很有意思,跟我以前接触的布局思想有很大不同,所以就自己测试了一些FlexBox的属性,一下是效果图:
RN的布局主要依赖于FlexBox系统,它有如下几个主要属性:
flex 视图的比重,这里注意了:In React Native flex
does not work the same way that it does in CSS
flexDirection 子视图在容器中排布的方向,这是用来确定主轴的 flexDirection controls which directions children of a Container Go
justifyContent 子视图在主轴的排列方式 justifyContent aligns children in the main direction
alignItems 子视图在主轴的交叉轴(次轴)排列方式 alignItems aligns children in the cross direction
alignSelf 子视图在次轴的排列方式,主要是用来重写父视图的alignItems
alignSelf controls how a child aligns in the cross direction, overriding the alignItems of the parent.
position 布局方式,默认是相对布局relative
flexWrap 是否包裹 ,默认值是nowrap
接下来看代码实现:
首先我们也仿照官方的列子写个Circle类来描述作为子视图的球
class Circle extends Component {
render() {
var size = this.props.size || 20
var backgroundColor = this.props.backgroundColor || '#dcdcdc'
return(
<View
style={{
borderRadius:size/2,
backgroundColor:backgroundColor,
width:size,
height:size,
margin:2,
shadowOffset:{width:4,height:4},
shadowColor:'#a9a9a9',
shadowOpacity:0.6
}}
/>
)}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
其次我们再写个CircleBlock类作为容器,其实就是小球的父视图:
class Circle extends Component {
render() {
var size = this.props.size || 20
var backgroundColor = this.props.backgroundColor || '#dcdcdc'
return(
<View
style={{
borderRadius:size/2,
backgroundColor:backgroundColor,
width:size,
height:size,
margin:2,
shadowOffset:{width:4,height:4},
shadowColor:'#a9a9a9',
shadowOpacity:0.6
}}
/>
)}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
先看看flexDirection这个属性有哪些值:
flexDirection: ReactPropTypes.oneOf([
'row',
'row-reverse',
'column',
'column-reverse'
]),
以下几个属性的实际效果:
<Text>flexDirection:row</Text>
<CircleBlock style={{flexDirection:'row'}}>
{minCircles}
</CircleBlock>
<Text>flexDirection:column</Text>
<CircleBlock style={{flexDirection:'column'}}>
{minCircles}
</CircleBlock>
<Text>flexDirection:row-reverse</Text>
<CircleBlock style={{flexDirection:'row-reverse'}}>
{minCircles}
</CircleBlock>
<Text>flexDirection:column-reverse</Text>
<CircleBlock style={{flexDirection:'column-reverse'}}>
{minCircles}
</CircleBlock>

justifyContent作为子视图在主轴的排列方式有这些值:
justifyContent: ReactPropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'space-between',
'space-around'
]),
看代码:
<Text>justifyContent:flex-start</Text>
<CircleBlock style={{justifyContent:'flex-start'}}>
{minCircles}
</CircleBlock>
<Text>justifyContent:center</Text>
<CircleBlock style={{justifyContent:'center'}}>
{minCircles}
</CircleBlock>
<Text>justifyContent:flex-end</Text>
<CircleBlock style={{justifyContent:'flex-end'}}>
{minCircles}
</CircleBlock>
<Text>justifyContent:space-between</Text>
<CircleBlock style={{justifyContent:'space-between'}}>
{minCircles}
</CircleBlock>
<Text>justifyContent:space-around</Text>
<CircleBlock style={{justifyContent:'space-around'}}>
{minCircles}
</CircleBlock>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
至于效果,是这样的

alignItems是子视图在主轴交叉轴的排列方式,有这些值
alignItems: ReactPropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'stretch'
]),
alignSelf做为对alignItems的重写,值与alignItems一样
<Text>alignItems: flex-start</Text>
<CircleBlock style={{alignItems:'flex-start',height:100}}>
{minCircles}
</CircleBlock>
<Text> alignItems:center</Text>
<CircleBlock style={{alignItems:'center',height:100}}>
{minCircles}
</CircleBlock>
<Text>alignItems:flex-end</Text>
<CircleBlock style={{alignItems:'flex-end',height:100}}>
{minCircles}
</CircleBlock>
flexWrap包裹
flexWrap: ReactPropTypes.oneOf([
'wrap',
'nowrap'
]),
下面是代码:
<Text>flexWrap:wrap</Text>
<CircleBlock style={{flexWrap:'wrap',height:150}}>
{[minCircles,minCircles,minCircles,minCircles,minCircles,minCircles]}
</CircleBlock>
<Text>flexWrap:nowrap</Text>
<CircleBlock style={{flexWrap:'nowrap',height:150}}>
{minCircles}
<CircleBlock style={{width:100,flexWrap:'wrap',marginVertical:40}}>
{minCircles}
</CircleBlock>
</CircleBlock>
<CircleBlock style={{flexWrap:'wrap',height:150}}>
<CircleBlock style={{width:100,flexWrap:'wrap',position:'absolute',marginVertical:40}}>
{minCircles}
</CircleBlock>
{minCircles}
</CircleBlock>
<CircleBlock style={{flexWrap:'nowrap',height:150}}>
{minCircles}
<CircleBlock style={{width:100,flexWrap:'wrap',alignSelf:'center'}}>
{minCircles}
</CircleBlock>
</CircleBlock>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
position当子视图需要在父视图里面精准定位是需要将子视图的position设置为absoulute
position: ReactPropTypes.oneOf([
'absolute',
'relative'
]),
而且是这里面的绝对布局可以理解是对容器剩余空间的布局,要注意区分这段代码的实现和效果:
实现
<CircleBlock style={{height:150}}>
{minCircles}
<CircleBlock style={{width:100,flexWrap:'wrap',marginVertical:40}}>
{minCircles}
</CircleBlock>
</CircleBlock>
<CircleBlock style={{height:150}}>
<CircleBlock style={{width:100,flexWrap:'wrap',position:'absolute',marginVertical:40}}>
{minCircles}
</CircleBlock>
{minCircles}
</CircleBlock>
<CircleBlock style={{height:150}}>
{minCircles}
<CircleBlock style={{width:100,flexWrap:'wrap',alignSelf:'center'}}>
{minCircles}
</CircleBlock>
</CircleBlock>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
效果:

源码已上传到Git上面了,下载源码