天天看点

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

2.4 react native的flexbox布局

无论是在移动平台还是web前端开发中,布局技术都是必不可少的。了解web开发的读者想必都听说过著名的css“盒子模型”,如图2.4所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.4 css“盒子模型”

css“盒子模型”依赖于position属性、浮动属性以及display属性来进行布局,所以,对于一些特殊但常用的布局(例如垂直居中)实现就比较困难。

于是,在2009年,w3c提出了一种新的方案——flexbox布局。flexbox(flexible box的缩写,又称弹性盒子布局)布局旨在提供一个更加有效的方式制定、调整和分布一个容器里的项目布局,即使他们的大小是未知或者动态的。flexbox布局的主要思想是让容器有能力让其子项目能够改变其宽度、高度(甚至顺序),以最佳方式填充可用空间(主要是为了适应所有类型的显示设备和屏幕大小)。

?小知识:w3c(world wide web consortium)指万维网联盟,该组织建立于1994年,其宗旨是通过促进通用协议的发展并确保其通用型,以激发web世界的全部潜能。

目前,主流浏览器都已经很好地支持flexbox布局,如图2.5所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.5 flexbox布局与主流浏览器的兼容性

react native实现了flexbox布局的大部分功能,并且在实际应用开发中也使用flexbox来实现布局。这不仅使react native的ui开发变得更加简单,还很好地解决了ios、android等屏幕适配的问题。

?提示:react native中flexbox布局的工作原理和web开发基本一致,只有少许差异。例如,默认值不同,react native中flexdirection属性的默认值是column而不是row,alignitems的默认值是stretch而不是flex-start,另外,flex只能指定一个数字值。

为了方便读者理解后面的代码,这里先简单介绍react native开发中flexbox布局的使用。

flexbox布局所使用的属性,简单来说,可以分为以下两个。

? 决定子组件排列规则的属性,例如,flexdirection、flexwrap、justifycontent以及alignitems等。

? 决定组件自身显示规则的属性,例如,alignself以及flex等。

下面分别简单介绍这些属性。

2.4.1 flexdirection设置组件的排列

flexdirection属性表明组件中子组件的排列方向,取值有column(默认值)、row以及row-reverse。

例如,在不设置flexdirection的情况下,下面代码中的子组件view1和view2是按照默认值column纵向排列的,代码如下:

01 export default class flexbox extends component {

02 render() {

03 return (

04 // 页面根view

05 // 子组件view1

06 // 子组件view2

07

08 );

09 }

10 }

11

12 const styles = stylesheet.create({

13 container: {

14 flex: 1.backgroundcolor:'gray',

15 },

16 view1: { //子组件view1的样式

17 height: 150,

18 width: 150,

19 backgroundcolor: 'red'

20 },

21 view2: { //子组件view2的样式

22 height: 150,

23 width: 150,

24 backgroundcolor: 'green'

25 }

26 });

?提示:为了节约篇幅,上述例子中只附上了关键代码,例如导入模块或组件的代码,形如import from 。但是读者在实际开发过程中,千万不要忘记先导入相关模块或组件,否则会发生错误。

效果如图2.6所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.6 flexdirection属性为column时的效果

当将flexdirection属性设置为row时,代码如下:

01 // 这里省略了没有修改的代码

02

03 const styles = stylesheet.create({

04 container: {

05 flex: 1, backgroundcolor.'gray',

06 flexdirection: 'row'

07 },

08 view1: { //子组件view1的样式

09 height: 150,

10 width: 150,

11 backgroundcolor: 'red'

12 },

13 view2: { //子组件view2的样式

14 height: 150,

15 width: 150,

16 backgroundcolor: 'green'

17 }

18 });

那么,子组件view1和view2将按照row进行横向排列,效果如图2.7所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.7 flexdirection属性为row时的效果

2.4.2 flexwrap设置是否换行

flexwrap属性表明子组件“溢出”父组件时是否进行换行,取值有nowrap(默认值)、wrap以及wrap-reverse。

这里,所谓的溢出是指子组件显示的区域超出了父组件的空间。为了模拟溢出的效果,下面修改view1和view2的大小,代码如下:

05 flex: 1, backgroundcolor:'gray',

08 view1: {

09 height: 200,

10 width: 200, // 增大了view1的宽度

13 view2: {

14 height: 200,

15 width: 200, // 增大了view2的宽度

由于没有设置flexwrap,所以当view2显示不全时,会按照默认值nowrap不进行换行,效果如图2.8所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.8 flexwrap属性为nowrap时的效果

当将flexwrap属性设置为wrap时,代码如下:

06 flexdirection: 'row',

07 flexwrap: 'wrap'

08 },

09 view1: {

10 height: 200,

11 width: 200,

12 backgroundcolor: 'red'

13 },

14 view2: {

15 height: 200,

16 width: 200,

17 backgroundcolor: 'green'

18 }

19 });

此时,由于view2和view1的总宽度(200 + 200 = 400)大于屏幕的宽度(使用的iphone 7宽度=375),所以view2将会换行显示,效果如图2.9所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.9 flexwrap属性为wrap时的效果

2.4.3 justifycontent设置横向排列位置

justifycontent属性表明组件中子组件横向排列在其父容器的哪个位置,取值有flex-start、flex-end、center、space-between以及space-around。

例如,想要实现子组件水平居中的效果,就可以将justifycontent的值设置为center,代码如下:

07 justifycontent: 'center'

10 height: 150,

11 width: 150,

15 height: 150,

16 width: 150,

效果如图2.10所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.10 justifycontent属性为center时的效果

2.4.4 alignitems设置纵向排列位置

alignitems属性表明组件中子组件纵向排列在其父容器的哪个位置,取值有flex-start、flex-end、center、baseline以及stretch。

alignitems属性和justifycontent的作用相似,只是justifycontent决定了子组件横向排列的位置,而alignitems决定了子组件纵向排列的位置。

如果想要实现子组件垂直居中的效果,那么就可以将alignitems的值设置为center,代码如下:

07 alignitems: 'center'

效果如图2.11所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.11 alignitems属性为center时的效果

在了解了justifycontent和alignitems属性的用法之后,想必读者很容易就能够自己实现水平垂直居中的效果了,代码如下:

07 justifycontent: 'center',

08 alignitems: 'center'

09 },

10 view1: {

12 height: 150,

12 width: 150,

13 backgroundcolor: 'red'

14 },

15 view2: {

16 height: 150,

17 width: 150,

18 backgroundcolor: 'green'

19 }

20 });

水平垂直居中的效果如图2.12所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.12 使用justifycontent和alignitems属性实现水平垂直居中效果

2.4.5 alignself设置特定组件的排列

alignself属性表明某个特定组件的排列情况,取值有auto、flex-start、flex-end、center以及stretch。

这里以center为例,代码如下:

06 },

07 view1: {

08 height: 150,

09 width: 150,

10 backgroundcolor: 'red'

11 },

12 view2: {

13 height: 150,

14 width: 150,

15 backgroundcolor: 'green',

16 alignself: 'center'

效果如图2.13所示。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.13 alignself属性为center时的效果

2.4.6 flex设置组件所占空间

flex属性可以让组件动态计算和配置自己所占用的空间大小,取值是数值。

如果想要view1和view2填满父组件,并且view1和view2的大小相同,使用flex就很容易实现,代码如下:

05 flex: 1

08 flex: 1,

09 backgroundcolor: 'red'

10 },

11 view2: {

12 flex: 1,

13 backgroundcolor: 'green'

14 }

15 });

效果如图2.14所示。

flex属性使用如此简单,但表现力却非常强大,它是flexbox布局实现自适应设备和屏幕尺寸的核心,读者需要在后面的react native开发中逐步熟练掌握flex属性的使用。

《React Native移动开发实战》一一2.4 React Native的Flexbox布局

图2.14 使用flex属性实现自适应屏幕的尺寸大小