React Native知識1-FlexBox 布局內容


一:理論知識點

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代碼出錯了,要么是樣式或者布局不正確引起;

 

 

最近有個妹子弄的一個關於擴大眼界跟內含的訂閱號,每天都會更新一些深度內容,在這里如果你感興趣也可以關注一下(嘿對美女跟知識感興趣),當然可以關注后輸入:github 會有我的微信號,如果有問題你也可以在那找到我;當然不感興趣無視此信息;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM