1. 程式人生 > >React Native學習筆記(四)Flex佈局

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,檢視執行後的效果,就能很快的掌握這一部分的屬性用法。