react-native 之布局总结

前端之家收集整理的这篇文章主要介绍了react-native 之布局总结前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

之前我们讲了很多react-native的基础控件,为了方便大家的理解,我们来对react-native的布局做一个总结,观看本节知识,你将看到。

  • 宽度单位和像素密度
  • flex的布局
  • 图片布局
  • 绝对定位和相对定位
  • padding和margin的区别和应用场合
  • 文本元素

宽度单位和像素密度

我们知道在Android中是用设备像素来作为单位的(后面又出现了百分比这么 一个概念),ios中后面也有了Auto Layout和1倍图,二倍图等概念(xib+storyboard)。然而react的宽度不支持百分比,那么React怎么提供尺寸的呢?PixelRatio,PixelRatio及像素密度,可以看看官方的介绍。

 var image = getImage({ width: 200 * PixelRatio.get(),height: 100 * PixelRatio.get() }); <Image source={image} style={{width: 200,height: 100}} />

flex的布局

我们知道一个div如果不设置宽度,默认的会占用100%的宽度, 为了验证100%这个问题, 做三个实验:

  1. 根节点上方一个View, 不设置宽度
  2. 固定宽度的元素上设置一个View, 不设置宽度
  3. flex的元素上放一个View宽度, 不设置宽度
 <Text style={[styles.text, styles.header]}> 根节点上放一个元素,不设置宽度 </Text> <View style={{height: 20,backgroundColor: '#333333'}} /> <Text style={[styles.text, styles.header]}> 固定宽度的元素上放一个View,不设置宽度 </Text> <View style={{width: 100}}> <View style={{height: 20,backgroundColor: '#333333'}} /> </View> <Text style={[styles.text, styles.header]}> flex的元素上放一个View,不设置宽度 </Text> <View style={{flexDirection: 'row'}}> <View style={{flex: 1}}> <View style={{height: 20,backgroundColor: '#333333'}} /> </View> <View style={{flex: 1}}/> </View>

来看一下运行的结果:

水平垂直居中

css 里边经常会将一个文本或者图片水平垂直居中,如果使用过css 的flexBox当然知道使用alignItems 和 justifyContent ,那如果用React Native如何实现呢?

<Text style={[styles.text, styles.header]}> 水平居中 </Text> <View style={{height: 100,backgroundColor: '#333333',alignItems: 'center'}}> <View style={{backgroundColor: '#fefefe',width: 30,height: 30,borderRadius: 15}}/> </View> <Text style={[styles.text, styles.header]}> 垂直居中 </Text> <View style={{height: 100,justifyContent: 'center'}}> <View style={{backgroundColor: '#fefefe', styles.header]}> 水平垂直居中 </Text> <View style={{height: 100,alignItems: 'center',borderRadius: 15}}/> </View>

网格布局

通常页面不是很复杂的时候,我们可以使用flex布局等分做到网格,复杂的那么就要用ListView实现,或者第三方控件。

等分的网格

<View style={styles.flexContainer}>
      <View style={styles.cell}>
        <Text style={styles.welcome}>
          cell1
        </Text>
      </View>
      <View style={styles.cell}>
        <Text style={styles.welcome}>
          cell2
        </Text>
      </View>
      <View style={styles.cell}>
        <Text style={styles.welcome}>
          cell3
        </Text>
      </View>
    </View>

    styles = {
        flexContainer: {
            // 容器需要添加direction才能变成让子元素flex
            flexDirection: 'row'
        },cell: {
            flex: 1,height: 50,backgroundColor: '#aaaaaa'
        },welcome: {
            fontSize: 20,textAlign: 'center',margin: 10
        },}


另一种方式可以参照我之前的实现: React Native实现九宫格效果

图片布局

<Text style={styles.welcome}> 100px height </Text> <Image style={{height: 100}} source={{uri: 'http://gtms03.alicdn.com/tps/i3/TB1Kcs5GXXXXXbMXVXXutsrNFXX-608-370.png'}} />

100px 高度, 可以看到图片适应100高度和全屏宽度,背景居中适应未拉伸但是被截断也就是cover。

 <Text style={styles.welcome}> 100px height with resizeMode contain </Text> <View style={[{flex: 1,backgroundColor: '#fe0000'}]}> <Image style={{flex: 1,height: 100,resizeMode: Image.resizeMode.contain}} source={{uri: 'http://gtms03.alicdn.com/tps/i3/TB1Kcs5GXXXXXbMXVXXutsrNFXX-608-370.png'}} /> </View>

contain 模式容器完全容纳图片图片自适应宽高。

 <Text style={styles.welcome}> 100px height with resizeMode cover </Text> <View style={[{flex: 1,resizeMode: Image.resizeMode.cover}} source={{uri: 'http://gtms03.alicdn.com/tps/i3/TB1Kcs5GXXXXXbMXVXXutsrNFXX-608-370.png'}} /> </View>

stretch模式图片被拉伸适应屏幕

 <Text style={styles.welcome}> set height to image container </Text> <View style={[{flex: 1,backgroundColor: '#fe0000',height: 100}]}> <Image style={{flex: 1}} source={{uri: 'http://gtms03.alicdn.com/tps/i3/TB1Kcs5GXXXXXbMXVXXutsrNFXX-608-370.png'}} /> </View>

绝对定位和相对定位

<View style={{flex: 1,backgroundColor: '#333333'}}> <View style={[styles.circle, {position: 'absolute',top: 50,left: 180}]}> </View> </View> styles = { circle: { backgroundColor: '#fe0000',borderRadius: 10,width: 20,height: 20 } }


和css的标准不同的是, 元素容器不用设置position:’absolute|relative’ 。

<View style={{flex: 1, {position: 'relative',left: 50,marginLeft: 50}]}> </View> </View>

padding和margin

我们知道在css中区分inline元素和block元素,既然react-native实现了一个超级小的css subset。那我们就来实验一下padding和margin在inline和非inline元素上的padding和margin的使用情况。
padding

 <Text style={[styles.text, styles.header]}> 在正常的View上设置padding </Text> <View style={{padding: 30,backgroundColor: '#333333'}}> <Text style={[styles.text, {color: '#fefefe'}]}> Text Element</Text> </View> <Text style={[styles.text, styles.header]}> 在文本元素上设置padding </Text> <View style={{padding: 0, {backgroundColor: '#fe0000',padding: 30}]}> text 元素上设置paddinga </Text> </View>

margin

 <Text style={[styles.text, styles.header]}> 在正常的View上设置margin </Text> <View style={{backgroundColor: '#333333'}}> <View style={{backgroundColor: '#fefefe',margin: 30}}/> </View> <Text style={[styles.text, styles.header]}> 在文本元素上设置margin </Text> <View style={{backgroundColor: '#333333'}}> <Text style={[styles.text,margin: 30}]}> text 元素上设置margin </Text> <Text style={[styles.text,margin: 30}]}> text 元素上设置margin </Text> </View>

文本元素

先看看文字有哪些支持的style属性

Attributes.style = {
    color string
    containerBackgroundColor string
    fontFamily string
    fontSize number
    fontStyle enum('normal','italic')
    fontWeight enum("normal",'bold','100','200','300','400','500','600','700','800','900')
    lineHeight number
    textAlign enum("auto",'left','right','center')
    writingDirection enum("auto",'ltr','rtl')
  }

Text的样式继承

实际上React-native里边是没有样式继承这种说法的, 但是对于Text元素里边的Text元素是可以继承的。到底是继承的最外层的Text的值呢,还是继承父亲Text的值呢?肯定是继承父亲Text的值。

 <Text style={[styles.text, styles.header]}> 文本样式继承 </Text> <View style={{backgroundColor: '#333333',padding: 10}}> <Text style={{color: 'white'}}> <Text style={{color: 'red'}} onPress={this.onPressTitle}> 文本元素{'\n'} <Text>我是white还是red呢?{'\n'} </Text> </Text> <Text>我应该是white的</Text> </Text> </View>

总结

针对上面的实例,我们做一个总结。

  • react 宽度基于pt为单位, 可以通过Dimensions 来获取宽高,PixelRatio 获取密度。
  • 基于flex的布局:
    view默认宽度为100%
    水平居中用alignItems,垂直居中用justifyContent
    基于flex能够实现现有的网格系统需求,且网格能够各种嵌套无bug
  • 图片布局
    通过Image.resizeMode来适配图片布局,包括contain,cover,stretch 三种模式
    默认不设置模式等于cover模式
    contain模式自适应宽高,给出高度值即可
    cover铺满容器,但是会做截取
    stretch铺满容器,拉伸
  • 绝对定位和相对定位
    定位相对于父元素,父元素不用设置position也行
    padding 设置在Text元素上的时候会存在bug。所有padding变成了marginBottom

  • 文本元素 文字必须放在Text元素里边 Text元素可以相互嵌套,且存在样式继承关系 numberOfLines 需要放在最外层的Text元素上,且虽然截取文字但是还是会占用空间

猜你在找的React相关文章