react-native 頁面佈局-flex佈局

  RN中的佈局我以爲主要包含這幾個部分:像素單位,佈局方式,組件,CSS。熟悉這幾點後,就是經驗的積累,見得多了作的多了佈局代碼寫起來天然就快許多。  html

  react native 的頁面佈局使用的是flex佈局,Flex是Flexible Box的縮寫,意爲"彈性佈局",用來爲盒狀模型提供最大的靈活性。flex只是一種元素佈局方式,因此任何一個元素均可以設定flex,而一個元素設定了flex以後,那麼它裏面的全部元素都是在這個容器內佈局。react

  1. Flex:1

  在RN中的flex佈局跟web中略有不一樣,RN中flex只能夠指定一個數字, 根據具體數字值來填充展現當前元素,「1」即表示100%撐滿當前容器,而該容器內的子元素只可以在該容器內區域佈局。ios

  2. 主次軸web

  容器內默認有兩根軸,橫軸和縱軸,當畫一個頁面時,首先要肯定該頁面或者該容器內是採用哪一個軸做爲主軸佈局,其實就是行佈局或者列布局。當肯定主軸以後,另一軸自動成爲副軸。RN中使用flexDirection來定義當前容器是使用何種佈局(column活row),默認爲column。justifyContent 和 alignItems 分別制定主軸和次軸的排列方式。ide

  flexDirection: column;row;佈局

  justifyContent:flex

    flex-start(默認,起始位置,通常都是左對齊);flexbox

    center(居中);spa

    flex-end(結尾,通常是右對齊);code

    space-around;space-between;

  alignItems:

    flex-start(默認,起始位置,通常都是左對齊);

    center(居中);

    flex-end(結尾,通常是右對齊);

    stretch(均勻分佈);

  當父容器指定了flex以後(好比1),那麼若是子元素的flex也都設置爲1,那麼這些子元素將會平均分配父容器的尺寸來佈局,就像以下代碼:  

<View style={{flex:1,flexDirection:'row',backgroundColor:'#ffffff'}}>
        <View style={{flex:1,backgroundColor:'red'}}></View>
        <View style={{flex:1,backgroundColor:'black'}}></View>
        <View style={{flex:1,backgroundColor:'blue'}}></View>
      </View>
   

 

 

flexDirection:'column'      flexDirection:'row'

 

  再舉個例子,子元素指定寬高,父容器採用space-between 和 space-around佈局,代碼以下:

     <View style={{flex:1,borderWidth:2,flexDirection:'column',backgroundColor:'#ffffff',justifyContent:'space-between', alignItems:'center'}}>
        <View style={{height:100,width:100,borderRadius:50,backgroundColor:'red'}}></View>
        <View style={{height:100,width:100,borderRadius:50,backgroundColor:'black'}}></View>
        <View style={{height:100,width:100,borderRadius:50,backgroundColor:'blue'}}></View>
      </View>

 

 

 

 justifyContent:'space-between'  justifyContent:'space-around'

 

  下面實現一個具體的例子,效果以下:

  

  這是一個表單頁面,從這個圖能夠得出:

  1. 外層是主軸按照column排列。行元素撐滿一行。

  2. 行元素高度固定,主軸按row排列,次軸的排列應該居中。

  3. 行元素有內襯,有分割線。

  4. 行元素內應該分左右兩部分,分別左右對齊。

  根據這幾點,咱們能夠大概寫出這樣的佈局:

class Layout extends Component {
  render() {
    return (
     <View style={{flex:1,backgroundColor:'#dddddd',flexDirection:'column',justifyContent:'center'}}>
      <View style={LayoutStyles.row}>
        <Text style={{flex:1}}>真實姓名</Text>
        <View style={{flex:1,alignItems:'flex-end'}}>
          <Text style={{color:'#999999'}}>John</Text>
        </View>
      </View>
      <View style={LayoutStyles.row}>
        <Text>手機號碼</Text>
        <View style={{flex:1,alignItems:'flex-end'}}>
          <Text style={{color:'#999999'}}>13812345678</Text>
        </View>
      </View>
     </View>
    );
  }
}

const LayoutStyles = StyleSheet.create({
  row: {
    backgroundColor:'#ffffff',
    height:47,
    flexDirection:'row',
    alignItems:'center',
    borderBottomWidth:0.5,
    borderBottomColor:'#dddddd',
    paddingHorizontal: 15
  }
});
View Code

這裏能夠看到, 在「手機號碼」這一行內,用兩個子元素Text和View分別設置flex:1來撐滿行元素,而後設置view的末端對齊。

而「真實姓名」這一行只對view設置了flex:1,也達到了這個效果。

經過給view加上border看一下:

能夠看出,若是在一個容器內,若是元素沒有設置flex,那麼默認會根據該元素的內容自動撐開寬度,而設置了flex:1的元素則會佔滿剩餘的空間。

那麼這裏給 「真實姓名」這行的右邊部分留下較大的空間,由於這裏要放一個輸入框,留下較大的區域能夠方便它點中以獲取焦點輸入。

borderWidth問題

這樣作使用borderWidth:0.5,這種寫法在ios上是能夠正常顯示,可是在部分Android機型上顯示異常。這個問題可使用 StyleSheet.hairlineWidth 來避免這個問題。

這裏分割線使用了行元素的下邊框來作,其實也能夠吧分割線做爲一個單獨的子元素來繪製,好比:

<View style={{height:1,backgroundColor:'#dddddd'}}></View>

 

分割線問題

跟效果圖對比行元素的分割線沒有撐滿,而是隨行內容同樣存在內襯。這個問題,若是採用上面的方法把分割線做爲子元素,則能夠解決。

若是使用邊框的話,能夠在行元素內再包一層View,外層View設置padding,內層view設置borderBottomWidth便可。

最終代碼:

class Layout extends Component {
  render() {
    return (
     <View style={{flex:1,backgroundColor:'#dddddd',flexDirection:'column',justifyContent:'center'}}>
      <View style={LayoutStyles.row}>
        <View style={LayoutStyles.rowContainer}>
          <Text>真實姓名</Text>
          <View style={{flex:1,alignItems:'flex-end',height:47}}>
            <TextInput style={LayoutStyles.inputTextName} underlineColorAndroid={'blue'}
            keyboardType={'default'} placeholder='請輸入' placeholderTextColor='#999999'
            defaultValue={'laochan'}
            maxLength={10}
            />
          </View>
        </View>
      </View>
      <View style={LayoutStyles.row}>
        <View style={LayoutStyles.rowContainer}>
          <Text style={{flex:1}}>手機號碼</Text>
          <View style={{flex:1,alignItems:'flex-end'}}>
            <Text style={{color:'#999999'}}>13812345678</Text>
          </View>
        </View>
      </View>
     </View>
    );
  }
}

const LayoutStyles = StyleSheet.create({
  row: {
    backgroundColor:'#ffffff',
    height:47,
    paddingHorizontal: 15
  },
  rowContainer: {
    flex: 1,
    flexDirection:'row',
    alignItems:'center',
    borderBottomWidth:StyleSheet.hairlineWidth,
    borderBottomColor:'#dddddd',
  },
  inputTextName: {
    flex:1,
    padding:0,
    fontSize:14,
    color: '#999999',
    textAlign: 'right',
    marginRight: 10
  }
});
View Code

 

 

參考資源:

http://reactnative.cn/docs/0.44/layout-with-flexbox.html#content

佈局樣式屬性:http://reactnative.cn/docs/0.44/layout-props.html

flex佈局:http://www.ruanyifeng.com/blog/2015/07/flex-examples.html

相關文章
相關標籤/搜索