一:理論知識點 1:什麼是FlexBox佈局? 彈性盒模型(The Flexible Box Module),又叫Flexbox,意為“彈性佈局”,旨在通過彈性的方式來對齊和分佈容器中內容的空間,使其能適應不同屏幕,為盒裝模型提供最大的靈活性。 Flex佈局主要思想是:讓容器有能力讓其子項目能夠改變 ...
一:理論知識點
1:什麼是FlexBox佈局?
彈性盒模型(The Flexible Box Module),又叫Flexbox,意為“彈性佈局”,旨在通過彈性的方式來對齊和分佈容器中內容的空間,使其能適應不同屏幕,為盒裝模型提供最大的靈活性。
Flex佈局主要思想是:讓容器有能力讓其子項目能夠改變其寬度、高度(甚至是順序),以最佳方式填充可用空間;
2:Flex佈局基於flex-flow流
容器預設存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start,結束位置叫做main end;交叉軸的開始位置叫做cross start,結束位置叫做cross end。
項目預設沿主軸排列,單個項目占據的主軸空間叫做main size,占據的交叉軸空間叫做cross size。
根據伸縮項目排列方式的不同,主軸和側軸方向也有所變化
3:在React中,Flexbox有6種容器屬性,6種項目屬性。而在React Native中,有4個容器屬性,2個項目屬性,分別是:
容器屬性:flexDirection flexWrap justifyContent alignItems
項目屬性:flex alignSelf
3.1: flexDirection容器屬性: `row | row-reverse | column | column-reverse`
該屬性決定主軸的方向(即項目的排列方向)。
row:主軸為水平方向,起點在左端。
row-reverse:主軸為水平方向,起點在右端。
column(預設值):主軸為垂直方向,起點在上沿。
column-reverse:主軸為垂直方向,起點在下沿。
3.2:flexWrap容器屬性: `nowrap | wrap | wrap-reverse`
預設情況下,項目都排在一條線(又稱"軸線")上。flex-wrap屬性定義,如果一條軸線排不下,如何換行。
3.2.1 nowrap(預設值):不換行
3.2.2 wrap:換行,第一行在上方
3.2.3 wrap-reverse:換行,第一行在下方。(和wrap相反)
3.3:justifyContent容器屬性:`flex-start | flex-end | center | space-between | space-around`
定義了伸縮項目在主軸線的對齊方式
flex-start(預設值):伸縮項目向一行的起始位置靠齊。
flex-end:伸縮項目向一行的結束位置靠齊。
center:伸縮項目向一行的中間位置靠齊。
space-between:兩端對齊,項目之間的間隔都相等。
space-around:伸縮項目會平均地分佈在行里,兩端保留一半的空間。
3.4:alignItems容器屬性:`flex-start | flex-end | center | baseline | stretch`
定義項目在交叉軸上如何對齊,可以把其想像成側軸(垂直於主軸)的“對齊方式”。
flex-start:交叉軸的起點對齊。
flex-end:交叉軸的終點對齊 。
center:交叉軸的中點對齊。
baseline:項目的第一行文字的基線對齊。
stretch(預設值):如果項目未設置高度或設為auto,將占滿整個容器的高度。
3.5:flex項目屬性:
“flex-grow”、“flex-shrink”和“flex-basis”三個屬性的縮寫, 其中第二個和第三個參數(flex-shrink、flex-basis)是可選參數。預設值為“0 1 auto”。
寬度 = 彈性寬度 * ( flexGrow / sum( flexGorw ) )
3.6:alignSelf項目屬性:
“auto | flex-start | flex-end | center | baseline | stretch”
align-self屬性允許單個項目有與其他項目不一樣的對齊方式,可覆蓋align-items屬性。
預設值為auto,表示繼承父元素的align-items屬性,如果沒有父元素,則等同於stretch。
二:代碼實例:
1:簡單佈局
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; class ReactNativeProject extends Component { render() { return ( <View style={styles.container}> <View style={styles.viewItem1}> </View> <View style={styles.viewItem2}> </View> <View style={styles.viewItem3}> </View> <View style={{flex:2,backgroundColor:'#bbceee',flexDirection:'row'}}></View> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1 }, viewItem1:{ flex:1, flexDirection:'row', height:50, backgroundColor:'#FF33CC' }, viewItem2:{ flex:1, flexDirection:'row', height:50, marginTop:15, backgroundColor:'#00FFFF' }, viewItem3:{ flex:1, flexDirection:'row', height:50, backgroundColor:'#CCBBFF' }, }); AppRegistry.registerComponent('ReactNativeProject', () => ReactNativeProject);
效果圖:
說明:return返回只能是一個對象,所以在最外層包含的一個View,裡面放置四個View,並對它們進行佈局;
最後一個View的flex屬性讓它比起其它的權重要大,所以高度會是其它的對應倍數值,上面還分開兩種寫法,一種是在下麵用樣式屬性編寫,另一個是直接在佈局裡面寫樣式,註意它們的差別,建議分開寫;裡面四個子View我們都讓它以flexDirection為row方式進行排列;
2:佈局屬性運用:
import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View } from 'react-native'; class ReactNativeProject extends Component { render() { return ( <View style={styles.container}> <View style={styles.viewItem1}> <View style={{flex:1,height:40,backgroundColor:'red'}}></View> <View style={{flex:1,height:40,backgroundColor:'blue',alignSelf:'center'}}></View> <View style={{flex:1,height:40,backgroundColor:'red',alignSelf:'flex-end'}}></View> </View> <View style={styles.viewItem2}> <View style={styles.viewItem2Child1}> </View> <View style={styles.viewItem2Child2}> </View> </View> <View style={styles.viewItem3}> <View style={styles.viewItem3Child1}> </View> <View style={styles.viewItem3Child2}> </View> <View style={styles.viewItem3Child3}> </View> </View> <View style={{flex:2,backgroundColor:'#bbceee',flexDirection:'row'}}> <View style={{flex:1,height:100,flexDirection:'row',justifyContent:'center',marginTop:30}}> <View style={{width:100,backgroundColor:'red'}}></View> <View style={{width:70,backgroundColor:'blue'}}></View> </View> </View> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1 }, viewItem1:{ flex:1, flexDirection:'row', height:50, backgroundColor:'#FF33CC' }, viewItem2:{ flex:1, flexDirection:'row', height:50, marginTop:15, backgroundColor:'#00FFFF', flexWrap:'wrap' }, viewItem2Child1: { width:200, height:30, backgroundColor:'green' }, viewItem2Child2: { width:200, height:30, backgroundColor:'red' }, viewItem3:{ flex:1, flexDirection:'row', height:50, backgroundColor:'#CCBBFF' }, viewItem3Child1:{ flex:1, backgroundColor:'#00ffbb' }, viewItem3Child2:{ flex:1, backgroundColor:'#aabbdd' }, viewItem3Child3: { flex:1, backgroundColor:'#0000ff' } }); AppRegistry.registerComponent('ReactNativeProject', () => ReactNativeProject);
在實例1的基礎上,對其它屬性進一步運用;效果圖如下:
第一個View包含三個View,主要是實現針對alignSelf屬性的運用;
第二個View包含二個View,兩個View的寬度之合大於屏幕寬度,主要是實現針對flexWrap屬性的運用;
第三個View包含三個View,主要是針對flex的運用
第四個View包含有兩個View,主要是針對justifyContent跟屬性marginTop的運用;
三:其它知識點:
1:獲取當前屏幕的寬度、高度、解析度
import Dimensions from 'Dimensions'; var { width, height, scale } = Dimensions.get('window'); render() { return ( <View> <Text> 屏幕的寬度:{width + '\n'} 屏幕的高度:{height + '\n'} 屏幕的解析度:{scale + '\n'} </Text> </View> ); }
2:預設寬度
我們都知道塊級標簽如果不設置寬度,通常都是獨占一行的,在React Native中的組件中需要設置flexDirection:'row',才能在同一行顯示,flex的元素如果不設置寬度,都會百分之百的占滿父容器。
3:水平、垂直居中
當alignItems、justifyContent傳center時與flexDirection的關係:
想理解這個很簡單,看我上班講的alignItems、justifyContent,心裡想著主軸和次軸就可以理解,justifyContent是主軸方向居中,而alignItems是次軸方向居中,flexDirection預設為column,所以誤區會認為alignItems為水平居中,justifyContent為垂直居中。
4:padding和margin
margin是指從自身邊框到另一個容器邊框之間的距離,就是容器外距離。在CSS中padding是指自身邊框到自身內部另一個容器邊框之間的距離,就是容器內距離,下麵這張是CSS的效果圖,只是名字不一樣(marginTop),原理都是一樣;
5:關於樣式
(1)普通內聯樣式:{{}},第一層{}是表達式,第二層{}是js對象;
<View style={{fontSize:40, width:80,}}> </View>
(2)調用樣式表:{樣式類.屬性}
<View style={styles.container}></View>
(3)樣式表和內聯樣式共存:{[]}
<View style={[styles.container, {fontSize:40, width:80}]}>
(4)多個樣式表:{[樣式類1, 樣式類2]}
<View style={[styles.container, styles.color]}>
6:React Native樣式屬性列表
"alignItems",
"alignSelf",
"backfaceVisibility",
"backgroundColor",
"borderBottomColor",
"borderBottomLeftRadius",
"borderBottomRightRadius",
"borderBottomWidth",
"borderColor",
"borderLeftColor",
"borderLeftWidth",
"borderRadius",
"borderRightColor",
"borderRightWidth",
"borderStyle",
"borderTopColor",
"borderTopLeftRadius",
"borderTopRightRadius",
"borderTopWidth",
"borderWidth",
"bottom",
"color",
"flex",
"flexDirection",
"flexWrap",
"fontFamily",
"fontSize",
"fontStyle",
"fontWeight",
"height",
"justifyContent",
"left",
"letterSpacing",
"lineHeight",
"margin",
"marginBottom",
"marginHorizontal",
"marginLeft",
"marginRight",
"marginTop",
"marginVertical",
"opacity",
"overflow",
"padding",
"paddingBottom",
"paddingHorizontal",
"paddingLeft",
"paddingRight",
"paddingTop",
"paddingVertical",
"position",
"resizeMode",
"right",
"rotation",
"scaleX",
"scaleY",
"shadowColor",
"shadowOffset",
"shadowOpacity",
"shadowRadius",
"textAlign",
"textDecorationColor",
"textDecorationLine",
"textDecorationStyle",
"tintColor",
"top",
"transform",
"transformMatrix",
"translateX",
"translateY",
"width",
"writingDirection"
四:問題
1:當出現下麵這張圖一般是JS代碼出錯了,要麼是樣式或者佈局不正確引起;