搜索
首页web前端js教程React Native使用Flexbox布局的介绍

React Native使用Flexbox布局的介绍

Jul 03, 2018 pm 05:58 PM
flexboxflexbox布局flex布局nativereact

React中引入了flexbox概念,flexbox是属于web前端领域CSS的一种布局方案,下面这篇文章主要给大家介绍了关于React Native基础入门之初步使用Flexbox布局的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

前言

在上篇中,笔者分享了部分安装并调试React Native应用过程里的一点经验,如果还没有看过的同学请点击《React Native基础&入门教程:调试React Native应用的一小步》。

在本篇里,让我们一起来了解一下,什么是Flexbox布局,以及如何使用。

一、长度的单位

在开始任何布局之前,让我们来首先需要知道,在写React Native组件样式时,长度的不带单位的,它表示“与设备像素密度无关的逻辑像素点”。

这个怎么理解呢?

我们知道,屏幕上一个发光的最小点,对应着一个pixel(像素)点。

假设下面三个矩形,代表三个屏幕大小一样的设备,但是,它们拥有的分辨率(resolution)不同:

图1.相同尺寸的设备 不同的分辨率

图上的每一个小格子,其实就代表了一个像素(pixel)。可以看到,一个像素点的大小,在这个三个物理尺寸一样但拥有不同分辨率的设备上,是不一样的。

如果我们以像素为单位来设置一个界面元素的大小,比如说2px的高度,那么这2px的长度上面的设备中就会是下面这个样子:

图2.不同分辨率下的2px实际高度

它们真实显示出的长度是不一样的。

我们想要一种长度单位,在同样物理尺寸大小的屏幕上(不论分辨率谁高谁低,只要物理尺寸大小一样即可),1个单位的长度所代表的物理尺寸是一样的。这种单位就应该是独立于分辨率的,把它起一个名字叫做 density-independent pixels,简称dp。这其实就是Android系统中所使用的长度单位。

举例来说,2dp宽,2dp高的内容,在不同分辨率但屏幕尺寸一样的设备上所显示出的物理大小是一样的。(一个题外话:有些Android开发者建议所有可点击的按钮,宽高都不应该少于48dp。)

图3. 2dp * 2dp大小的内容 在同样尺寸的屏幕中所占据的物理大小一致

Android中字体大小使用另外一个单位,叫做scale independent pixels,简称sp。这个单位和dp很类似,不过它通常是用在对字体大小的设置中。通过它设置的字体,可以根据系统字体大小的变化而变化。

pixel与dp存在一个公式:px = dp * (dpi/160)。

dpi表示dot per inch,是每英寸上的像素点,它也有个自己的计算公式,具体这里就不展开了。只需要知道我们之所以要使用一个独立于设备分辨率的单位,主要是为了让应用在不同分辨率的设备中,看起来一致。

在RN中,同样也拥有一个类似于dp的长度单位。如果我们想知道自己的屏幕以这种长度的计量下是多少单位,可以通过引入react-native包中的Dimensions拿到,同时还可以查看本机的像素比例是多少。

import {
  Text,
  View,
  Dimensions,
  PixelRatio
} from 'react-native';
const { height, width } = Dimensions.get('window');
const pxRatio = PixelRatio.get();
<View style={styles.container}>
  <Text style={styles.welcome}>
    {`width: ${width}, height: ${height}`}
  </Text>
  <Text style={styles.welcome}>
    {`pixel radio: ${pxRatio}`}
  </Text>
</View>

显示如下:

图4. 当前手机的屏幕信息

它反映出,当前手机屏幕的宽度占据360个单位,高度占据640个单位。像素比例是3,实际上这就是一个 1080 * 1920 像素的手机。其中1080 = width * pixelRadio, 1920 = height * pixelRatio

二、Flexbox布局

Flexbox布局,也就是弹性盒模型布局。也许有Android开发经验的朋友还对LinearLayout,RelativeLayout,FrameLayout等布局方法记忆犹新,但是对于更了解CSS的Web开发者而言,使用flexbox布局肯定会让他感受到更加顺手的开发体验。

RN中的flexbox布局,其实源于CSS中的flexbox(弹性盒子)布局规范。其实它在CSS中还处于Last Call Working Draft(最终征求意见稿)阶段,但是主流浏览器对它都有了良好的支持。在RN中,几乎完全借鉴了其中的布局语义,同时更没有浏览器兼容的烦恼,用起来是很方便的。RN中只是把CSS的属性用camelCase写法代替连字符写法。后面还还会看到,默认的flex方向也不同。

理解弹性盒模型布局,首先要知道四个最基本的概念:Flex Container(容器),Flex Item(项),Flex Direction(方向)和Axis(轴)。

1.Flex Container

就是包裹内容的容器,需要把它的display设置为‘flex'(或者'inline-flex')。

以下6个属性设置在容器上。

  • alignItems 指定item在侧轴上的对齐方式

  • alignContent 指定item在多条轴上的对齐方式

  • flexDirection 指定主轴方向

  • flexWrap 指定item在主轴方向如何换行

  • flexFlow flexDirection属性和flexWrap属性的简写形式

  • justifyContent 指定item在主轴上的分布方式

2.Flex Item

容器做直接包裹的元素。所谓弹性盒布局,通常想要布局的东西就是它们。

以下6个属性设置在项目上。

  • alignSelf 每个item可以单独设置对齐方式 覆盖Flex Container给设置的alignItems

  • order 指定item排列顺序 数字越小越靠前

  • flexGrow 指定item的拉伸比例

  • flexShrink 指定item的压缩比例

  • flexBasis 指定item在分配多余空间之前,占主轴的大小

  • flex 其实是 flexGrow flexShrink flexBasis的简写

3.Flex Direction and Axis

在弹性盒子中,项目默认沿着main axis(主轴)排列,和主轴垂直的轴叫做cross axis,叫做侧轴,或者交叉轴。

在盒子中,排列项目又四个方向:水平的正反两个,垂直的正反两个。

结构代码:

<View>
 <View style={styles.row}>
 <Text style={styles.item}>1</Text>
 <Text style={styles.item}>2</Text>
 <Text style={styles.item}>3</Text>
 </View>
 <View style={styles.rowReverse}>
 <Text style={styles.item}>1</Text>
 <Text style={styles.item}>2</Text>
 <Text style={styles.item}>3</Text>
 </View>
 <View style={styles.column}>
 <Text style={styles.item}>1</Text>
 <Text style={styles.item}>2</Text>
 <Text style={styles.item}>3</Text>
 </View>
 <View style={styles.columnReverse}>
 <Text style={styles.item}>1</Text>
 <Text style={styles.item}>2</Text>
 <Text style={styles.item}>3</Text>
 </View>
</View>

样式代码:

row: {
backgroundColor: &#39;#ffe289&#39;,
flexDirection: &#39;row&#39;
},
rowReverse: {
flexDirection: &#39;row-reverse&#39;
},
column: {
backgroundColor: &#39;#ffe289&#39;,
flexDirection: &#39;column&#39;
},
columnReverse: {
flexDirection: &#39;column-reverse&#39;
},

图5. flexDirection

由于网上关于flex布局讲解的资源挺丰富的,读者可以参考最后给出的连接,或者自行上网搜索,CSS中的和RN是相通的。

这里主要分享个人在学习过程中,觉得容易引起混淆的两个小点。

首先,justify-content和align-content这两个属性,可能比较容易搞错它们作用的方向。

其中,justify-content是设置items沿着主轴上是如何分布的。align-content是设置items沿着侧轴如何对齐的。

还是拿之前的例子,默认情况下,flex的方向是column(这个与移动端与web页面不同,在web页面用CSS设置flex布局,默认的fiex-direction是row,即水平从左往右)。

在移动端,主轴默认是垂直方向,从上往下。让我们把它的高度设置高一点,放3个item在里面:

结构代码:

<View>
 <View style={styles.defaultFlex}>
 <Text style={styles.item}>1</Text>
 <Text style={styles.item}>2</Text>
 <Text style={styles.item}>3</Text>
 </View>
</View>

样式代码:

defaultFlex: {
height: 300,
backgroundColor: &#39;#ffe289&#39;,
display: &#39;flex&#39;
}

图6. 默认的flex

justify-content设置items在主轴方向的如何分布,比如,如果我们加上justifyContent: 'space-between'

defaultFlex: {
height: 300,
backgroundColor: &#39;#ffe289&#39;,
display: &#39;flex&#39;,
justifyContent: &#39;space-between&#39;
}

items就沿主轴分开了。

图7. justifyContent: 'space-between'

如果我们设置alignItems: 'center',项目就沿侧轴(这里就是水平轴)居中了。注意这两个属性是可以同时起作用的。

图8. justifyContent: 'space-between' 以及 alignItems: 'center'

然后,值得指出的是,flex这个属性,其实是flexGrow, flexShrink, flexBasis(对应的CSS属性flex-grow, flex-shrink和flex-basis)三个属性的结合。

我们通常在移动端看到的flex:1这个设置,其实是对flex-grow的设置。后者的默认值为0。使用把flex-grow设置为正整数的方法,可以让item按比例分布,或者在其他item为固定大小时撑满剩余的盒子空间,就仿佛具有弹性一样。

结构代码:

<View style={styles.container}>
 <View style={styles.flex1}></View>
 <View style={styles.flex2}></View>
 <View style={styles.flex3}></View>
</View>

样式代码:

container: {
flex: 1
},
flex1: {
// height: 99,
flexGrow: 1,
backgroundColor: &#39;orange&#39;,
},
flex2: {
flexGrow: 2,
backgroundColor: &#39;lightblue&#39;,
},
flex3: {
flexGrow: 3,
backgroundColor: &#39;green&#39;,
},

图9. 按比例分布

需要注意的是,如果父容器的尺寸为零(即没有设置宽高,或者没有设定flex),即使子组件如果使用了flex,也是无法显示的。

所以这里最外层的使用了flex布局的,flex:1,表示让它占据了垂直的整个空间。

三、小小实战演练

让我们来简单使用flex布局,对之前的例子稍加调整,实现一个头部,底部固定高度,中间内容占满剩下的屏幕的布局:

第一步,调整结构:

<View style={styles.container}>
 <View style={styles.header}></View>
 <View style={styles.body}></View>
 <View style={styles.footer}></View>
</View>

调整样式:

container: {
flex: 1
},
header: {
height: 60,
backgroundColor: &#39;orange&#39;,
},
body: {
flexGrow: 1,
backgroundColor: &#39;lightblue&#39;,
},
footer: {
height: 60,
backgroundColor: &#39;green&#39;,
}

图10. 有头尾的布局

第二部,给header添加标题。

我们让头部的分成3部分,左边模拟一个返回按钮,中间显示标题文字,右边模拟一把小叉:

<View style={styles.header}>
 <Text style={styles.back}>返回</Text>
 <Text style={styles.title}>这是一个标题</Text>
 <Text style={styles.exit}>×</Text>
</View>

需要把header的flexDirection设置为水平方向:

header: {
height: 60,
backgroundColor: &#39;orange&#39;,
flexDirection: &#39;row&#39;,
alignItems: &#39;center&#39;
},
back: {
color: &#39;white&#39;,
marginLeft: 15
},
title: {
flexGrow: 1,
fontSize: 20,
color: &#39;white&#39;,
textAlign: &#39;center&#39;
},
exit: {
marginRight: 20,
fontSize: 20,
color: &#39;white&#39;
}

图11. header有了标题

第三步,我们可以把footer三等分,模拟成菜单的样子:

<View style={styles.footer}>
 <Text style={styles.firstMenu}>添加</Text>
 <Text style={styles.menu}>删除</Text>
 <Text style={styles.menu}>修改</Text>
</View>

添加样式:

footer: {
height: 60,
backgroundColor: &#39;green&#39;,
flexDirection: &#39;row&#39;,
alignItems: &#39;center&#39;
},
menu: {
flexGrow: 1,
textAlign: &#39;center&#39;,
borderColor: &#39;white&#39;,
borderLeftWidth: 1,
color: &#39;white&#39;
},
firstMenu: {
flexGrow: 1,
textAlign: &#39;center&#39;,
color: &#39;white&#39;
},

图12. footer三等分 模拟菜单

最后,让我们在body里也填入几个带按钮的输入框。

引入TextInput和Button组件,然后把它们分三组放入body中,

<View style={styles.body}>
 <View style={styles.inputRow}>
  <TextInput style={styles.textInput}></TextInput>
  <Button style={styles.btn} onPress={() => {}} title="确定"></Button>
 </View>
 <View style={styles.inputRow}>
  <TextInput style={styles.textInput}></TextInput>
  <Button style={styles.btn} onPress={() => {}} title="非常确定"></Button>
 </View>
 <View style={styles.inputRow}>
  <TextInput style={styles.textInput}></TextInput>
  <Button style={styles.btn} onPress={() => {}} title="确定一定以及肯定"></Button>
 </View>
</View>

添加样式:

body: {
flexGrow: 1,
backgroundColor: &#39;lightblue&#39;,
},
inputRow: {
flexDirection: &#39;row&#39;,
alignItems: &#39;center&#39;,
marginLeft: 10,
marginRight: 10
},
textInput: {
flex: 1
},
btn: {
minWidth: 60
}

flex布局的一个常用实践是,部分内容固定宽高,让剩下的内容自适应。

像上面这样,我们给Button有一个最小宽度,且TextInput的flexGrow为1,这样的做法可以实现,TextInput总是占满剩下的宽度,且可伸缩。

看了上面的例子,是否觉得在React Native中使用Flexbox布局也挺简单呢?

希望这是个不错的开始。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

基于React和Redux的SSR的实现方法

echarts同一页面中四个图表切换的js数据交互方法

以上是React Native使用Flexbox布局的介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

JavaScript的演变:当前的趋势和未来前景JavaScript的演变:当前的趋势和未来前景Apr 10, 2025 am 09:33 AM

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

神秘的JavaScript:它的作用以及为什么重要神秘的JavaScript:它的作用以及为什么重要Apr 09, 2025 am 12:07 AM

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python还是JavaScript更好?Python还是JavaScript更好?Apr 06, 2025 am 12:14 AM

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境