這段時間熟悉了一下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
}}
/>
)}
}
其次我們再寫個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
}}
/>
)}
}
先看看flexDirection這個屬性有哪些值:
flexDirection: ReactPropTypes.oneOf([
'row', //我的理解就是橫排
'row-reverse', //橫排顛倒,其實從效果上來看就是把row的一切都反過來
'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>
至於效果,是這樣的
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>
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>
效果:
源碼已上傳到git上面了,下載源碼