React Native學習筆記(四)Flex佈局
1、基本樣式
對於一個元件,定義元件的佈局樣式通過style屬性來定義。
例如:
<Text style = {{color: '#ff0000', fontSize: 15}}> 學習佈局 </Text>
這裡通過style屬性,定義了Text文字的字型顏色和字型大小。這裡第一個大括號是:JSX語法,第二個大括號是:javaScript物件,我們把需要定義的樣式都以物件的方式寫在這個大括號裡。
我們也可以把一個樣式賦給一個變數:然後傳進去。
例如:
<Text style = {styles.textContent}> 測試 </Text>
// ...
const styles = StyleSheet.create({
textContent: {
color: '#ff0000',
fontSize: 1,
},
});
這裡我們使用React.StyleSheet建立了一個 JS物件,那麼在元件上引用是這樣的:style={{物件名稱.物件屬性}}。
知道元件中如何使用樣式了以後,我們自然會想到一個元件都支援那些樣式。此時我們可以通過查詢一些手冊去學習都有哪些樣式,我們還可以通過編譯器報的錯誤提示來檢視。例如:我們隨意寫一個它不支援的屬性test。
const styles = StyleSheet.create ({
textContent: {
color: '#ff0000',
fontSize: 1,
test: 2,
},
});
如上圖,我們可以看到一些報錯資訊。在這些提示中給出了有效的樣式提示。
2、Flexbox佈局
彈性佈局的主要思想是讓容器有能力來改變專案的寬度和高度,以填滿可用空間(主要是為了容納所有型別的顯示裝置和螢幕尺寸)的能力。
flexbox是一個整體模組,而不是單一的一個屬性。它們之中有一些是在父容器上設定,而有一些則是在子容器上設定。
flex佈局涉及到了兩個概念:主軸和縱軸。如下圖示意:
在React Native中主軸就是flexDirection定義的方向。另一個軸就為縱軸了。
為了方便表述,下面定義兩個表述詞:
container:定義為父容器,有些屬性是作用在父容器上的,即需要設定在父容器上。
item:定義為子容器或當前容器(元件),有些屬性是作用在當前容器上的,即需要設定在子容器上。
1)flex屬性
flex屬性是作用在item上的。當一個元件,定義了flex屬性時,表示該元素是可伸縮的。當然flex的屬性值是大於0的時候才伸縮,其小於和等於0的時候不伸縮。
<View style = {styles.container}>
<View style = {styles.subContainer} >
<View style = {styles.item1}>
<Text style = {styles.textContent}> item1 </Text>
</View>
<View style = {styles.item2}>
<Text style = {styles.textContent}> item2 </Text>
</View>
<View style = {styles.item3}>
<Text style = {styles.textContent}> item3 </Text>
</View>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
},
subContainer: {
flex: 1,
flexDirection: 'row',
},
item1: {
flex: 1,
height: 40,
backgroundColor: '#ff0000',
},
item2: {
flex: 1,
height: 40,
backgroundColor: '#00ff00',
},
item3: {
flex: 1,
height: 40,
backgroundColor: '#0000ff',
},
textContent: {
color: '#ffffff',
fontSize: 20,
},
如下圖:
因為item1、item2、item3的flex屬性都設定為1,所以它們都是可以伸縮佈局的。flex也可以理解為權重。代表所佔的比例。如上圖它們的flex都設定為1時,它們是等寬的。如果設定它們的flex屬性分別為:5:10:5,那麼會得到如下的圖:
2)flexDirection屬性
flexDirection在React-Native中只有兩個屬性,一個是row(橫向伸縮)和column(縱向伸縮)。在上面的設定中就已經運用到了flexDirection屬性。subContainer定義的樣式中就已經設定了flexDirection為row,設定了它為橫向伸縮。該屬性值預設是縱向伸縮的。
3)justifyContent屬性
justifyContent屬性定義Item在主軸上的對齊方式。它的可取值為[flex-start, flex-end, center, space-between, space-around]
例如:
<View style = {styles.container}>
<View style = {styles.item1}>
<Text style = {styles.textContent}> item1 </Text>
</View>
<View style = {styles.item2}>
<Text style = {styles.textContent}> item2 </Text>
</View>
<View style = {styles.item3}>
<Text style = {styles.textContent}> item3 </Text>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
item1: {
width: 40,
height: 40,
backgroundColor: '#ff0000',
},
item2: {
width: 40,
height: 40,
backgroundColor: '#00ff00',
},
item3: {
width: 40,
height: 40,
backgroundColor: '#0000ff',
},
textContent: {
color: '#ffffff',
fontSize: 15,
},
});
其他屬性值如:flex-start, flex-end, center, space-between, space-around
讀者可以自行去嘗試它們的效果。
4)alignItems屬性
Items 在垂直軸的對齊方式。它的可選值為:[flex-start, flex-end, center, stretch]。在上面的程式碼中container樣式新增一個屬性值:
在這個效果圖中設定container的值為:
container: {
flex: 1,
justifyContent: 'space-around',
alignItems: 'center',
},
alignItem屬性的flex-start, flex-end, center很容易知道它們的排布,下面說一下stretch。如下圖:預設stretch如果Item未設定寬度(高度),將佔滿整個容器的寬度(高度)。
5)alignSelf屬性
align-self屬性允許單個專案有與其他專案不一樣的對齊方式,可覆蓋父container的alignItems屬性。
<View style = {styles.container}>
<View style = {styles.item1}>
<Text style = {styles.textContent}> item1 </Text>
</View>
<View style = {styles.item2}>
<Text style = {styles.textContent}> item2 </Text>
</View>
<View style = {styles.item3}>
<Text style = {styles.textContent}> item3 </Text>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'space-around',
alignItems: 'center',
},
item1: {
width: 40,
height: 40,
backgroundColor: '#ff0000',
},
item2: {
height: 40,
width: 40,
alignSelf: 'flex-start',
backgroundColor: '#00ff00',
},
item3: {
width: 40,
height: 40,
backgroundColor: '#0000ff',
},
textContent: {
color: '#ffffff',
fontSize: 15,
},
});
設定item2的alignSelf為flex-start,它覆蓋了父檢視的alignItems: ‘center’。
預設值為auto。 表示如果父容器定義了alignItems則繼承alignItems,否則則取為stretch佈局。
6) flex-wrap屬性
flex-wrap設定或檢索container的item超出父容器時是否換行。它有兩個值:[wrap, nowrap]。該屬性作用於container上。
nowrap:當子元素溢位父容器時不換行。(預設方式)
wrap:當子元素溢位父容器時自動換行。
如下程式碼演示:
<View style = {styles.container}>
<View style = {styles.item1}>
<Text style = {styles.textContent}> item1 </Text>
</View>
<View style = {styles.item2}>
<Text style = {styles.textContent}> item2 </Text>
</View>
<View style = {styles.item3}>
<Text style = {styles.textContent}> item3 </Text>
</View>
</View>
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
flexWrap: 'wrap',
},
item1: {
width: 300,
height: 40,
backgroundColor: '#ff0000',
},
item2: {
height: 40,
width: 300,
backgroundColor: '#00ff00',
},
item3: {
width: 300,
height: 40,
backgroundColor: '#0000ff',
},
textContent: {
color: '#ffffff',
fontSize: 15,
},
});
執行效果如圖:
設定container樣式的flexWrap屬性後,通過上圖的對比,就可以看到該屬性所起的作用。
在學習這一部分的時候,通過執行小的demo,檢視執行後的效果,就能很快的掌握這一部分的屬性用法。