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

相关文章
相关标签/搜索