一止剖、簡(jiǎn)介
2009年揭鳞,W3C提出了一種新的方案----Flex布局缀磕,可以簡(jiǎn)便缘圈、完整劣光、響應(yīng)式地實(shí)現(xiàn)各種頁面布局。
flex是Flexible Box的縮寫糟把,意為"彈性布局"绢涡,用來為盒狀模型提供最大的靈活性。采用flex布局的元素遣疯,稱為flex容器(flex Container)雄可,簡(jiǎn)稱"容器"。它的所有子元素自動(dòng)成為容器成員缠犀,稱為flex項(xiàng)目(flex item)数苫,簡(jiǎn)稱"項(xiàng)目"。"容器"對(duì)應(yīng)iOS中的父view概念辨液,"項(xiàng)目"對(duì)應(yīng)iOS中的子view概念虐急。
React Native中的Flexbox的工作原理和web上的CSS基本一致,當(dāng)然也存在少許差異滔迈。首先是默認(rèn)值不同:flexDirection的默認(rèn)值是column而不是row止吁,而flex也只能指定一個(gè)數(shù)字值。
所有說燎悍,RN中的Flex布局來自于CSS敬惦,但是有點(diǎn)特殊性。RN中可以用到的屬性谈山,可以在官方文檔中查閱俄删。
二、RN中Flex布局用法
1奏路、基本概念
容器默認(rèn)存在兩根軸:主軸(main axis)和交叉軸(cross axis)抗蠢。主軸的開始位置(與邊框的交叉點(diǎn))叫做main start,結(jié)束位置叫做main end思劳;交叉軸的開始位置叫做cross start迅矛,結(jié)束位置叫做cross end。項(xiàng)目默認(rèn)沿主軸排列潜叛。單個(gè)項(xiàng)目占據(jù)的主軸空間叫做main size秽褒,占據(jù)的交叉軸空間叫做cross size。
Flex布局與Android的線性布局(LinearLayout)有點(diǎn)類似威兜,都可以設(shè)置布局方向销斟,對(duì)齊方式,以及項(xiàng)目的布局占位權(quán)重椒舵,區(qū)別是flex容器中項(xiàng)目分布的總長(zhǎng)度超出屏幕寬度蚂踊,超出的那部分項(xiàng)目不可見,項(xiàng)目不會(huì)變形笔宿,或者可以設(shè)置flexWrap屬性犁钟,讓容器可以分行布局棱诱,所有項(xiàng)目都能顯示出來。
對(duì)比iOS:FlexBox沒有XY軸的概念涝动,主軸和交叉軸不是固定的迈勋;也沒有坐標(biāo)值(x,y)的概念。后文會(huì)介紹醋粟!
2靡菇、Flex基本屬性
flex屬性聲明在:/node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js
`// https://developer.mozilla.org/en-US/docs/Web/CSS/flex-direction
flexDirection: ReactPropTypes.oneOf([
'row',
'column'
]),
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex-wrap
flexWrap: ReactPropTypes.oneOf([
'wrap',
'nowrap'
]),
// How to align children in the main direction
// https://developer.mozilla.org/en-US/docs/Web/CSS/justify-content
justifyContent: ReactPropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'space-between',
'space-around'
]),
// How to align children in the cross direction
// https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
alignItems: ReactPropTypes.oneOf([
'flex-start',
'flex-end',
'center',
'stretch'
]),
// How to align the element in the cross direction
// https://developer.mozilla.org/en-US/docs/Web/CSS/align-items
alignSelf: ReactPropTypes.oneOf([
'auto',
'flex-start',
'flex-end',
'center',
'stretch'
]),
//children scale in container view
// https://developer.mozilla.org/en-US/docs/Web/CSS/flex
flex: ReactPropTypes.number,`
由上述代碼,我們可以看到flex的屬性并不多米愿,而且很好記憶厦凤,以下將會(huì)一一介紹
flex屬性可以分為容器屬性和項(xiàng)目屬性
其中容器屬性包括:flexDirection,justifyContent育苟,alignItems泳唠,flexWrap
項(xiàng)目屬性包括:flex,alignSelf
以下介紹會(huì)使用到一些代碼和圖片宙搬,先定義兩個(gè)簡(jiǎn)單組件笨腥,方便理解
var Circle = React.createClass({
render : function(){
;var size = this.props.size || 20;
var color = this.props.color || '#527fe4';
return <View style={{backgroundColor:color,borderRadius:size/2,height:size,width:size,margin:1}}/>
},
});
//定義一個(gè)放置標(biāo)題和項(xiàng)目的容器勇垛,傳入的value屬性將會(huì)是需要介紹的flex屬性
var Value = React.createClass({
render : function(){
var value =
<View>
<Text style={styles.valueText}>{this.props.title}</Text>
<View style={[styles.valueContainer,this.props.value]}>
{this.props.children}
</View>
</View>;
return value;
},
});
//定義一個(gè)數(shù)組放置5個(gè)圓
var children = [<Circle/>,<Circle/>,<Circle/>,<Circle/>,<Circle/>];```
###2.1 容器屬性
1脖母、flexDirection:布局方向,決定主軸的方向闲孤,默認(rèn)值是column谆级,即縱向布局
值 | 描述 |
---|---|
row | 橫向布局,主軸為水平方向 |
column | 縱向布局讼积,主軸為豎直方向 |
row:橫向布局
代碼:
<Value title='row' value={{flexDirection:'row'}}>
{children}
</Value>
視圖:
![97158B7B-CC32-4769-847F-A08CE7DC209B.png](http://upload-images.jianshu.io/upload_images/2305876-db41bc5aaf500302.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
column:縱向布局
代碼:
<Value title='column' value={{flexDirection:'column'}}>
{children}
</Value>
視圖:
![20160710123731597.jpg](http://upload-images.jianshu.io/upload_images/2305876-602391e00b4d8894.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2肥照、justifyContent:主軸方向?qū)R方式,子組件和容器的對(duì)齊方式勤众,默認(rèn)值是flex-start舆绎,即主軸的開端
值 | 描述 |
---|---|
flex-start | 主軸開端 |
center | 居中 |
flex-end | 主軸末端 |
space-between | 項(xiàng)目與項(xiàng)目之間插入相等空隙 |
space-around | 項(xiàng)目?jī)膳圆迦胂嗟瓤障?/td> |
flex-start:主軸開端
代碼:
<Value title='flex-start' value={{flexDirection:'row', justifyContent:'flex-start'}}>
{children}
</Value>
視圖:
![20160710123752426.jpg](http://upload-images.jianshu.io/upload_images/2305876-68f3e2bfcc2d0acf.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
center:主軸的中間位置
代碼:
<Value title='center' value={{flexDirection:'row',justifyContent:'center'}}>
{children}
</Value>
視圖:
![20160710123811612.jpg](http://upload-images.jianshu.io/upload_images/2305876-6ed71436d80ddc31.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
flex-end:主軸的末端位置
代碼:
<Value title='flex-end' value={{flexDirection:'row',justifyContent:'flex-end'}}>
{children}
</Value>
視圖:
![20160710123828083.jpg](http://upload-images.jianshu.io/upload_images/2305876-c329b7e35a156230.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
space-between:項(xiàng)目與項(xiàng)目之間插入相同距離的空隙
代碼:
<Value title='space-between' value={{flexDirection:'row',justifyContent:'space-between'}}>
{children}
</Value>
視圖:
![20160710123845099.jpg](http://upload-images.jianshu.io/upload_images/2305876-edef1daaa8fd306a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
space-around:項(xiàng)目?jī)膳圆迦胂嗤嚯x的空隙
代碼:
<Value title='space-around' value={{flexDirection:'row',justifyContent:'space-around'}}>
{children}
</Value>
視圖:
![20160710123859802.jpg](http://upload-images.jianshu.io/upload_images/2305876-72248aac6862b6d3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
3、alignItems:交叉軸方向?qū)R方式们颜,子組件和容器的對(duì)齊方式吕朵,默認(rèn)值flex-start,即交叉軸開端
值 | 描述 |
---|---|
flex-start | 交叉軸開端 |
center | 交叉軸居中 |
flex-end | 交叉軸末端 |
flex-start:交叉軸開端
![20160710123930800.jpg](http://upload-images.jianshu.io/upload_images/2305876-d5b418a97eb8a6c6.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
center:交叉軸的中間位置
![20160710123938397.jpg](http://upload-images.jianshu.io/upload_images/2305876-b65919e47a239d3a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
flex-end:交叉軸的末端位置
![20160710123946034.jpg](http://upload-images.jianshu.io/upload_images/2305876-2975afe455bd778b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
flexWrap:包含內(nèi)容窥突,默認(rèn)值是nowrap努溃,不包裹所有內(nèi)容
值 | 描述 |
---|---|
nowrap | 項(xiàng)目沿主軸方向布局,超出容器長(zhǎng)度的部分不可見 |
wrap | 項(xiàng)目沿主軸布局所需長(zhǎng)度大于容器總長(zhǎng)度時(shí)阻问,分行布局梧税,所有項(xiàng)目?jī)?nèi)容都可見 |
nowrap:不包裹內(nèi)容
代碼:
<Value title='nowrap' value={{flexWrap:'nowrap',flexDirection:'row'}}>
{children}{children}{children}{children}
</Value>
視圖:
![20160710124011461.jpg](http://upload-images.jianshu.io/upload_images/2305876-ea4d01dc45b04a19.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
wrap:包裹內(nèi)容
代碼:
<Value title='wrap' value={{flexWrap:'wrap',flexDirection:'row'}}>
{children}{children}{children}{children}
</Value>
視圖:
![20160710124019144.jpg](http://upload-images.jianshu.io/upload_images/2305876-fc66d654740f827f.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
###2.2 項(xiàng)目屬性
1、flex:布局權(quán)重
值 | 描述 |
---|---|
>=0 | 項(xiàng)目占位權(quán)重 |
1:0:flex=0的項(xiàng)目占用空間僅為內(nèi)容所需空間,flex=1的項(xiàng)目會(huì)占據(jù)其余所有空間
代碼:
<Value title='1:0' value={{flexDirection:'row'}}>
<Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'red',fontSize:20,paddingHorizontal:10}}>flex=1</Text>
<Text style={{color:'white',textAlign:'center',backgroundColor:'yellow',fontSize:20,paddingHorizontal:10}}>flex=0</Text>
</Value>
![20160710124042149.jpg](http://upload-images.jianshu.io/upload_images/2305876-b79e28b56be5c95b.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2:1
代碼:
<Value title='2:1' value={{flexDirection:'row'}}>
<Text style={{color:'white',flex:2,textAlign:'center',backgroundColor:'blue',fontSize:20}}>flex=2</Text>
<Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'green',fontSize:20}}>flex=1</Text>
</Value>
![20160710124050258.jpg](http://upload-images.jianshu.io/upload_images/2305876-b97631c340b6e98c.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
1:1:1:1
代碼:
<Value title='1:1:1:1' value={{flexDirection:'row'}}>
<Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'red',fontSize:20}}>flex=1</Text>
<Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'yellow',fontSize:20}}>flex=1</Text>
<Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'blue',fontSize:20}}>flex=1</Text>
<Text style={{color:'white',flex:1,textAlign:'center',backgroundColor:'green',fontSize:20}}>flex=1</Text>
</Value>
![20160710124105801.jpg](http://upload-images.jianshu.io/upload_images/2305876-dcbb3b1500328ef8.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2第队、alignSelf:項(xiàng)目交叉軸方向自身對(duì)齊方式哮塞,子組件和容器的對(duì)齊方式,會(huì)覆蓋alignItems的設(shè)置斥铺。
值 | 描述 |
---|---|
flex-start | 開端 |
center | 居中 |
flex-end | 末端 |
代碼:
<Value title='alignSelf' value={{flexDirection:'row',height:30,alignItems:'center'}}>
<View style={{alignSelf:'flex-start'}}>
<Circle/>
</View>
<View style={{alignSelf:'flex-end'}}>
<Circle/>
</View>
<View style={{alignSelf:'flex-start'}}>
<Circle/>
</View>
<View style={{alignSelf:'flex-end'}}>
<Circle/>
</View>
<View style={{alignSelf:'flex-start'}}>
<Circle/>
</View>
</Value>
視圖:
![20160710124121472.jpg](http://upload-images.jianshu.io/upload_images/2305876-97483e4bb247ab2d.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
##3、 Layout的其他屬性
layout除了flex屬性之外坛善,當(dāng)然還有其他屬性晾蜘,同樣聲明在:/node_modules/react-native/Libraries/StyleSheet/LayoutPropTypes.js
width: ReactPropTypes.number,
height: ReactPropTypes.number,
top: ReactPropTypes.number,
left: ReactPropTypes.number,
right: ReactPropTypes.number,
bottom: ReactPropTypes.number,
margin: ReactPropTypes.number,
marginVertical: ReactPropTypes.number,
marginHorizontal: ReactPropTypes.number,
marginTop: ReactPropTypes.number,
marginBottom: ReactPropTypes.number,
marginLeft: ReactPropTypes.number,
marginRight: ReactPropTypes.number,
padding: ReactPropTypes.number,
paddingVertical: ReactPropTypes.number,
paddingHorizontal: ReactPropTypes.number,
paddingTop: ReactPropTypes.number,
paddingBottom: ReactPropTypes.number,
paddingLeft: ReactPropTypes.number,
paddingRight: ReactPropTypes.number,
borderWidth: ReactPropTypes.number,
borderTopWidth: ReactPropTypes.number,
borderRightWidth: ReactPropTypes.number,
borderBottomWidth: ReactPropTypes.number,
borderLeftWidth: ReactPropTypes.number,
position: ReactPropTypes.oneOf([
'absolute',
'relative'
]),
屬性 | 類型 | 描述 |
---|---|---|
width | number | 容器或者項(xiàng)目的寬度 |
height | number | 容器或者項(xiàng)目的高度 |
top,bottom,left,right | number | 在父容器的上下左右偏移量 |
margin | number | 留邊,留邊的空間不屬于容器或者項(xiàng)目自身空間 |
marginHorizontal | number | 水平方向留邊 |
marginVertical | number | 垂直方向留邊 |
padding | number | 填充眠屎,填充的空間輸入容器或者項(xiàng)目自身空間 |
paddingHorizontal | number | 水平方向填充 |
paddingVertical | number | 垂直方向填充 |
borderWidth | number | 邊界寬度 |
position | enum | 位置方式:absolute與relative |
position:默認(rèn)值為relative
值 | 描述 |
---|---|
absolute | 絕對(duì)布局 |
relative | 相對(duì)布局 |
react的默認(rèn)位置方式是relative剔交,項(xiàng)目是一個(gè)接一個(gè)排列下去的,absolute為絕對(duì)布局改衩,一般會(huì)與left和top屬性一起使用岖常。有時(shí)候我們需要實(shí)現(xiàn)某些項(xiàng)目重疊起來,absolute屬性就能發(fā)揮作用了葫督,例如下圖:
![20160710124137682.jpg](http://upload-images.jianshu.io/upload_images/2305876-1f7da8cfd80aa011.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
react的基本組件暫時(shí)不支持以圖片作為背景竭鞍,所以這里的的轉(zhuǎn)入是一個(gè)文本組件,而紅色的圓形是一個(gè)圖片組件橄镜,在iOS里面組件也可以作為容器偎快,圖片可以正常顯示,但是在Android里面洽胶,可能存在些問題晒夹,如果使用組件作為容器都會(huì)出現(xiàn)圖片變得好奇怪,所以就可以absoulte來解決問題了姊氓。代碼如下:
<View style={{width:80,height:80,alignItems:'center',justifyContent:'center'}}>
<Image style={{position:'absolute',left:0,top:0,resizeMode:'contain',width:80,height:80}} source={require('image!finance_usercenter_ic_into')}/>
<Text style={{width:80,textAlign:'center',color:'white',fontSize:16}}>轉(zhuǎn)入</Text>
</View>
這里的View跟Android的View有點(diǎn)不一樣丐怯,View是可以作為容器也可以作為項(xiàng)目,View作為容器還有其他很多屬性翔横,例如backgroundColor读跷,borderWidth,borderColor禾唁,opacity等等舔亭,這里不一一介紹。
**注意:absolute時(shí)蟀俊,控件的上下左右是相對(duì)于container钦铺;relative時(shí),控件用的是marginLeft肢预,marginTop矛洞,marginBottom,marginRight,分別相對(duì)于left沼本,top噩峦,bottom,right的元素(container或者item)抽兆。**
4 布局的尺寸說明
react native的寬高是不需要帶單位的识补,那些width,height辫红,padding凭涂,margin的賦值都直接是數(shù)字的,當(dāng)你設(shè)定width:10贴妻,在IOS的話就是設(shè)置了10pt寬度切油,而在Android上面是10dp,在做項(xiàng)目時(shí)名惩,辛勤的美工會(huì)幫我們標(biāo)出所有UI控件的寬澎胡,高,邊距等等娩鹉,他們用的單位也是dp攻谁,所以賦值style中寬高時(shí),直接填入數(shù)字即可弯予。
alignItems 和 alignSelf區(qū)別
alignItems
調(diào)整伸縮項(xiàng)目在側(cè)軸上的定位方式
可選值: flex-start , flex-end , center , stretch
![20160710123625127.jpg](http://upload-images.jianshu.io/upload_images/2305876-2e1383a71736424a.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
alignSelf
alignSelf 屬性會(huì)覆蓋容器的 alignItems 屬性巢株,取值和用法 alignItems 一樣。
可選值: auto , flex-start , flex-end , center , stretch
參考鏈接:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
http://blog.csdn.net/teng_ontheway/article/details/51870951
https://segmentfault.com/a/1190000002658374