[React Native Android 安利系列]样式与布局的书写

欢迎你们收看react-native-android系列教程,跟着本系列教程学习,能够熟练掌握react-native-android的开发,你值得拥有:
https://segmentfault.com/blog...javascript

react-native-android的布局不一样于以往的网页布局,采用的是一种组件的方式,使用js来定义样式表。接下来,咱们会一块儿详细的了解这些react-native的样式,及全部样式的做用、用法。而且,咱们将经过一些小例子,来实践这些样式。css

1. react-native中的样式

打开咱们以前建立的项目,咱们看到,在最下方,是简单的布局样式。形式自己是javascript的对象形式。观其内容,则是咱们熟悉的css样式。前端

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },  
  welcome: {
    fontSize: 20, 
    textAlign: 'center',
    margin: 10, 
  },  
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },  
});

而样式的应用也是web开发者比较熟悉的『内联style』的方式,如图1.1
090326_XsAA_1177792.png
图1.1
在但愿应用的标签上,将style属性填写为咱们建立的styles,这样就能将样式应用于咱们的标签上了。java

可是这里请注意,有一些细节仍是和普通的css不同的。react

1. react-native的样式的属性名,须要使用驼峰方式。android

2. react-native的样式应用于某一个组件上的话,该样式不会继承下去,而是只应用于设置该style的节点上(Text相关样式除外,Text嵌套的话,其文字属性也会应用于子元素)。git

3. react-native的样式中width/height的单位是DP。并非PX,这点请同窗们注意一下,不然,按照设计图设计出来的东西会至关的难看。。。。。github

4. 应用于组件的style属性上的样式,能够不止一个,可使用多个,以逗号分隔。如 style={styles.a,styles.b}web

5. 咱们终于能够在样式中使用变量啦,好比咱们想要一个元素的宽度等于屏幕的宽度,能够直接这么写:segmentfault

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        width: Dimensions.get('window').width,
    },
});

2. react-native中全部能用到的属性

接下来咱们来看一下android中,全部咱们能利用的上的属性吧:

2.1 背景相关(background)

backfaceVisibility 改元素背面面向屏幕时是否可见

backgroundColor 元素的背景色

2.2 布局相关(flex)

alignItems flex布局元素中,子元素沿纵轴排列方式

alignSelf flex元素中,本项元素的纵轴对其方式

flex 这里指代flex-grow,描述了元素的宽度比例值

flexDirection 指代flex元素的排列方向

flexWrap 指代flex元素的换行方式,取值为 nowrap|wrap|wrap-reverse

justifyContent 指代flex元素在横轴上的排列方式,以后会进行详解。

2.3 布局相关(margin/padding/border)

margin 留白

marginBottom 底部留白

marginLeft 左外留白

marginRight 右外留白

marginTop 上外留白

marginVertical 上下外留白的简写,若是marginTop与marginBottom同样的话,能够直接用这个值代替

marginHorizontal 左右外留白的简写

borderColor 总体边框颜色

borderRadius 总体边框的圆角

borderWidth 总体边框的宽

borderStyle 边框样式 dotted solid double dashed等

borderBottomColor 底边框颜色

borderBottomWidth 底边框宽度

borderLeftColor 左边框颜色

borderLeftWidth 左边框宽度

borderRightColor 右边框颜色

borderRightWidth 右边框宽度

borderTopColor 上边框颜色

borderTopWidth 上边框宽度

borderBottomLeftRadius 左下角圆角边框

borderBottomRightRadius 右下角圆角边框

borderTopLeftRadius 上边框左圆角

borderTopRightRadius 上边框右圆角

padding 内留白

paddingBottom

paddingTop

paddingLeft

paddingRight

paddingHorizontal

paddingVertical

height 元素高度,包含padding与border

width 元素宽度,包含padding与border

2.4 定位相关

position

top

right

bottom

left

2.5 文字相关

color

fontFamily

fontSize

fontStyle

fontWeight

textAlign

textDecorationColor

textDecorationLine

textDecorationStyle

letterSpacing

lineHeight

2.6 阴影相关

shadowColor 阴影色IOS only

shadowOffset 阴影距离IOS only

shadowOpacity 阴影透明度IOS only

shadowRadius 阴影半径 IOS only

elevation 仰角 android only

2.7 其余

opacity

overflow

resizeMode

rotation

scaleX

scaleY

transform

transformMatrix

translateX

translateY

writingDirection

3 React属性逐个详解+示例

3.1 背景相关属性

3.1.2 backgroundColor 元素的背景色

backgroundColor相信你们并不陌生,就是一个元素的背景色,支持多种值的选择

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.colorBlock, styles.back1]}></View>
                <View style={[styles.colorBlock, styles.back2]}></View>
                <View style={[styles.colorBlock, styles.back3]}></View>
                <View style={[styles.colorBlock, styles.back4]}></View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    colorBlock: {
        height: 100,
        width: 100,
    },  
    back1: {
        // 普通的16进制值
        backgroundColor: '#000'
    },  
    back2: {
        // 颜色名称的简写
        backgroundColor: 'blue'
    },  
    back3: {
        // 颜色的RGB表示
        backgroundColor: 'rgb(255, 0, 255)',
    },  
    back4: {
        // 颜色的RGBA表示
        backgroundColor: 'rgba(255, 0, 255, 0.5)',
    },
});

效果以下,具体代码,参见本文后例子中的--index.android.js.backgroundColor(如图图3.2.1)
191642_zW5O_1177792.png
图3.2.1

3.1.1 backfaceVisibility 改元素背面面向屏幕时是否可见

我的感受这里reactNative在android下的实现的有点BUG,就是这个属性没有达到预期的效果,

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.rotateBlock, styles.back1]}>
                    <Text>Hello</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back2]}>
                    <Text>Hello</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back3]}>
                    <Text>Hello</Text>
                </View>
            </View>
        );  
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        marginTop: 50,
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },
    back1: {
        transform: [{rotateY: '135deg'}],
        backfaceVisibility: 'visible'
    },
    back2: {
        backfaceVisibility: 'hidden',
        transform: [{rotateY: '180deg'}],
    },
    back3: {
        backfaceVisibility: 'hidden',
        transform: [{rotateY: '360deg'}],
    },
});

出现的效果如图3.1.1:
194310_88XY_1177792.png
图3.1.1
元素的背面也展示了出来。具体详见本文例子中的:index.android.js.backfaceVisibility。

3.2 布局相关(flex)

因为react-native的布局比较复杂,因此咱们稍后会花费一整篇的篇幅,对其进行讲解。

3.3 布局相关(margin/padding/border)

height,width 没必要多说。border,padding,margin的基本属性,作前端的同窗也是轻车熟路了。这里,给原生开发,而且以前没有作过前端的同窗们小小的科普一下。
194824_Bd9v_1177792.png
图3.3
传统的网页设计的,使用css的盒子模型,来搭建元素的布局。如图3.3所示。一个元素由,内容、填充(内留白)、边框、边界(外留白)组成。对应上了咱们这一组 布局相关的属性。

3.3.1 让咱们来作一个盒子模型的示例

首先,咱们设定一个View,宽高都为100。

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.rotateBlock, styles.back1]}>
                    <Text>Hello</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },
    back1: {
        
    },
});

效果如图3.3.1所示:
205116_sHAC_1177792.png
图3.3.1
展现了一个普通的100*100的正方形(如图3.3.1.1)。
接着,咱们为其加上50的padding。
205525_8XLS_1177792.png
图3.3.1.1
发现其宽高并无变,代表咱们这里的盒子模型其实有别与传统的盒子模型。它的宽高是包含了padding(内留白)在内的。
咱们接着,将border也加上宽度:

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        padding: 30,
        borderWidth: 10,
        borderColor: '#000',
        backgroundColor: '#0f0',
    },
    back1: {
        
    },
});

会发现,其实宽度*高度(100*100)也是包含了border的(如图3.3.1.2)。
210413_PIQF_1177792.png
图3.3.1.2
因此,咱们react-native的盒模型,能够认为是border-box的模型。即,width或者height的设定值,包含了padding、border和content。这点,也请有前段开发经验的同窗注意一下。
咱们再来看一看margin。

const styles = StyleSheet.create({
    container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        padding: 30,
        borderWidth: 10,
        borderColor: '#000',
        margin: 10,
        backgroundColor: '#0f0',
    },
    back1: {
        
    },
});

效果如图3.3.1.3
210845_CKxr_1177792.png
图3.3.1.3
咱们看到margin并不会被算到width、height的值当中。而是产生了外部留白。

3.3.2 特殊属性解释

这里请注意,marginvVerticl,marginHorizontal这两个属性是(marginTop,marginBottom)与(marginLeft,marginRight)的简写。

同理可证,paddingVertical,paddingHorizontal。这几个属性在css中没有,可是react提供了更为简洁的设置方法。

borderStyle,这个属性是设置border的展示样式的。其可取的值有:

'solid'(默认), 'dotted', 'dashed',可是通过本人实验,在android环境下,几个属性貌似不能用。

具体详见本文例子中的:index.android.js.boxLayout文件。

3.4 定位相关

熟悉前端的同窗确定对position这个属性特别的亲切。这是网页布局中很是常见的一种定位方式。而对于不熟悉前端的同窗来讲呢,咱们也会一块儿来看看,这组属性到底有什么做用。

一个元素若是不设定position去定位话,默认会造成文档流。每一个元素会按顺序出如今文档流中,排到本身的位置上。

举个例子,咱们有三个view,普通排列,正如咱们所想,是一个挨着一个,顺序出如今被安排的位置上:

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.rotateBlock, styles.back1]}>
                    <Text>Hello1</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back2]}>
                    <Text>Hello2</Text>
                </View>
                <View style={[styles.rotateBlock, styles.back3]}>
                    <Text>Hello3</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
            
    },  
    back2: {
    },  
    back3: {
            
    },  
});

效果如图3.4.1
220850_xIDk_1177792.png
图3.4.1
若是咱们将第二个view的定位设定为absolute(绝对定位),那么会变成什么样呢,如图3.4.2?

back2: {
    position: 'absolute',
},

221058_8Z98_1177792.png
图3.4.2
咱们发现,第二个view不见了,那么它去哪儿了呢?它已经脱离了咱们的文档流,留下1和3,还规规矩矩的排在那里。咱们为了找到第二个view,目前到底在哪儿,来尝试着更改其top和left。top/right/bottom/left决定了定位元素的位置。咱们先调整其left为20,如图3.4.3

back2: {
    position: 'absolute',
    backgroundColor: '#f00',
    left: 30,
},

222313_B70i_1177792.png
图3.4.3
可见第二个元素虽然脱离了文档流可是仍是在原先的位置上。只不过是被后面的第三个view给盖住了。这和咱们在前端的常识不一样。不过也能够理解为,此时的top与left。设定为了与本身未脱离文档流时候的top和left一致。

若是两个元素都设定为position:absolute,咱们会看到排列顺序是按照文档流出现的顺序,下面的盖住上面的。可是若是咱们像调整一下覆盖的顺序呢?咱们在这里要介绍一下elevation,这个属性,这个属性比较奇特,他不只能够控制覆盖顺序(就像z-index那样),同时会产生一个阴影特效,稍后咱们会讲到。

咱们来实验一下,如图3.4.4:

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>Hello1</Text>
                </View>
                <View style={[styles.shadowBlock, styles.back2]}>
                    <Text>Hello2</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    shadowBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
        position: 'absolute',
    },  
    back2: {
        position: 'absolute',
    },  
});

232251_E1Kh_1177792.png
图3.4.4
咱们看到,文档流中后出现的hello2覆盖掉了hello1。那么咱们将两个元素都设置上elevation属性,再来看看(如图3.4.5):

back1: {
    position: 'absolute',
    elevation: 1,
},
back2: {
    position: 'absolute',
},

232708_veq0_1177792.png
图3.4.5
咱们看到,剧情发生了反转,有elevation的hello1,覆盖住了在文档流中后出现的hello2。其实hello2的elevation值,咱们能够认为是0,

结论:当两个元素,显示上有重叠的时候,elevation大的元素,会覆盖掉elevation值较小的元素。

相应的例子代码,在本文例子中的index.android.js.elevation文件里。

上面,咱们讨论了position为绝对定位的时候的排布规律,而若是position设定为relative的话,会怎样呢(如图3.4.6)?

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    rotateBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
            
    },  
    back2: {
        position: 'relative',
        backgroundColor: '#f00',
    },  
    back3: {
            
    },  
});

223214_E0n1_1177792.png
图3.4.6
咱们看到,并无发生什么异样,文档流仍是那个文档流,but,若是此时,咱们设置了left: 20的话,咱们再来看看效果,如图3.4.7

back2: {
    position: 'relative',
    left: 20,
    backgroundColor: '#f00',
},

223542_KkX1_1177792.png
图3.4.7

第二个view并未脱离文档流,而是按照本身以前的位置,进行了偏移。

如上述所示,其实各位发现react的定位,并不复杂。另外,元素默认的position,是relative,因此其实上面的例子,咱们不用指定position,也能获得一样的效果:

back2: {
    left: 20,
    backgroundColor: '#f00',
},

具体代码详见本文例子中的:index.android.js.boxLayout文件。

3.5 文字相关

react-native中,文字相关的样式设定,咱们将会单独拿出一节来讨论。请各位关注,很快就会产出。

3.6 阴影相关

阴影可让咱们的应用变得更加的立体,呈现出更好的展现效果。让咱们一块儿将阴影系列的属性一一实践。

shadowColor

shadowOffset

shadowOpacity

shadowRadius

这些属性,目前只适用于IOS系统,android的话,有一个替代属性elevation,这个属性影响着元素的z-index,就是绝对定位时的覆盖顺序(上面咱们提到过),也会在元素上产生一个阴影。

咱们能够利用这个属性来设定阴影,elevation的值会影响阴影的offset(如图3.6.1):

class hellowReact extends Component {
    constructor(props) {
        super(props);
    }   
    render() {
        return (
            <View style={styles.container}>
                <View style={[styles.shadowBlock, styles.back1]}>
                    <Text>Hello1</Text>
                </View>
            </View>
        );  
    }   
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },  
    shadowBlock: {
        height: 100,
        width: 100,
        backgroundColor: '#0f0',
    },  
    back1: {
        elevation: 5,
    },  
});

233545_0fUV_1177792.png
图3.6.1
就这样,咱们成功的看到了阴影,不过这个属性要慎用,由于它会影响z轴上的排列顺序。

具体代码详见本文例子中的:index.android.js.elevation2文件。

3.7 其余属性

因为其余属性较为散乱也较为复杂,咱们接下来将专门花去一篇的篇幅,来逐一讲解这些属性,请各位看官关注个人博客,很快就会更新。

本文中提到的例子,均在下面的github上,须要的话请下载:

https://github.com/houyu01/re...

接下来,我会详细的带你们一块儿了解一下react-native的flex布局,不要走开,请关注我.......

若是喜欢本文请点击下方的推荐哦,你的推荐会变为我继续更文的动力。

以上内容仅表明笔者我的观点,若有意见请通知笔者。

相关文章
相关标签/搜索