当前位置: 首页 > news >正文

React Native 样式及其布局

React Native 样式及其布局

参考 https://reactnative.cn/docs/flexbox

一、样式

在 React Native 中,你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 CSS 的命名,只是按照 JS 的语法要求使用了驼峰命名法,例如将background-color改为backgroundColor

style属性可以是一个普通的 JavaScript 对象。这是最简单的用法,因而在示例代码中很常见。你还可以传入一个数组——在数组中位置居后的样式对象比居前的优先级更高,这样你可以间接实现样式的继承。

实际开发中组件的样式会越来越复杂,我们建议使用StyleSheet.create来集中定义组件的样式。比如像下面这样:

import React from 'react';
import {StyleSheet, View, Text} from 'react-native';const App = () => {return (<View style={styles.container}><Text style={styles.red}> 红色的文字 </Text><Text style={styles.bigBlue}> 蓝色的文字 </Text><Text style={[styles.bigBlue, styles.red]}>bigBlue, then red</Text><Text style={[styles.red, styles.bigBlue]}>red, then bigBlue</Text></View>);
};const styles = StyleSheet.create({container: {marginTop: 50,},bigBlue: {color: 'blue',fontWeight: 'bold',fontSize: 30,},red: {color: 'red',},
});export default App;

一行一行来解释:

  • 第1行是需要导入React 包,是因为 react 在编译 jsx 后的需要使用 React.createElement

  • 第2行是需要导入StyleSheet、View、Text三个库

  • 第4~13行是App组件里的样式

  • 第15~27行是声明styles属性,方便App组件里使用这个属性里的子属性

  • 第29行就是导出App组件,方便index.js里渲染这个组件

    image-20231102160648668

最后效果如下图所示:

rn样式

二、高度与宽度

2.1 固定宽高

组件的高度和宽度决定了其在屏幕上显示的尺寸。

最简单的给组件设定尺寸的方式就是在样式中指定固定的widthheight。React Native 中的尺寸都是无单位的,表示的是与设备像素密度无关的逻辑像素点。

一种是这样写

import React from 'react';
import {View} from 'react-native';const FixedDimensionsBasics = () => {return (<View><View style={{width: 50, height: 50, backgroundColor: 'blue'}} /><View style={{width: 100, height: 100, backgroundColor: 'red'}} /><View style={{width: 200, height: 200, backgroundColor: 'yellow'}} /></View>);
};export default FixedDimensionsBasics;

一种是这样写

import React from 'react';
import {StyleSheet, View} from 'react-native';const FixedDimensionsBasics = () => {return (<><View style={styles.smallStyle} /><View style={styles.midStyle} /><View style={styles.bigStyle} /></>);
};const styles = StyleSheet.create({smallStyle: {width: 50,height: 50,backgroundColor: 'blue',},midStyle: {width: 100,height: 100,backgroundColor: 'red',},bigStyle: {width: 200,height: 200,backgroundColor: 'yellow',},
});export default FixedDimensionsBasics;

上面代码运行如下:

RN高度和宽度

个人更加推荐使用第二种写法,便于统一编写样式和查看样式。因为通常而言一个文件里会有很多种样式,如果都写在view组件的括号里,视觉效果看起来会很不友好,而且去排查样式问题的时候也不利于去排查到底是哪块的问题。

2.2 弹性(Flex)宽高

在组件样式中使用flex可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用flex:1来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex值的比)。

组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的widthheight,也没有设定flex,则父容器的尺寸为零。其子组件如果使用了flex,也是无法显示的。

import React from 'react';
import {StyleSheet, View} from 'react-native';const FlexDimensionsBasics = () => {return (// 试试去掉父View中的`flex: 1`。// 则父View不再具有尺寸,因此子组件也无法再撑开。// 然后再用`height: 300`来代替父View的`flex: 1`试试看? => 结果是三个view平分父view的300高度的<View style={styles.container}><View style={styles.powderblueStyle} /><View style={styles.skyblueStyle} /><View style={styles.steelblueStyle} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,},powderblueStyle: {flex: 1,backgroundColor: 'powderblue',},skyblueStyle: {flex: 2,backgroundColor: 'skyblue',},steelblueStyle: {flex: 3,backgroundColor: 'steelblue',},
});export default FlexDimensionsBasics;

上述代码效果图如下:

flex弹性宽高

如果上述代码的container下的样式flex不为1,设置的是height: 300的话,则效果如下所示:

剩余铺满

三、使用Flexbox布局

我们在 React Native 中使用 flexbox 规则来指定某个组件的子元素的布局。Flexbox 可以在不同屏幕尺寸上提供一致的布局结构。

一般来说,使用flexDirectionalignItemsjustifyContent三个样式属性就已经能满足大多数布局需求。

React Native 中的 Flexbox 的工作原理和 web 上的 CSS 基本一致,当然也存在少许差异。首先是默认值不同:flexDirection的默认值为column(而不是row),alignContent默认值为 flex-start(而不是 stretch), flexShrink 默认值为0 (而不是1), 而flex只能指定一个数字值。

3.1 Flex

flex 属性决定元素在主轴上如何填满可用区域。整个区域会根据每个元素设置的 flex 属性值被分割成多个部分。

在下面的例子中,在设置了flex: 1的容器 view 中,有红色,黄色和绿色三个子 view。红色 view 设置了flex: 1,黄色 view 设置了flex: 2,绿色 view 设置了flex: 31+2+3 = 6,这意味着红色 view 占据整个区域的1/6,黄色 view 占据整个区域的2/6,绿色 view 占据整个区域的3/6

import React from "react";
import { StyleSheet, Text, View } from "react-native";const Flex = () => {return (<View style={[styles.container, {// Try setting `flexDirection` to `"row"`.flexDirection: "column"}]}><View style={{ flex: 1, backgroundColor: "red" }} /><View style={{ flex: 2, backgroundColor: "darkorange" }} /><View style={{ flex: 3, backgroundColor: "green" }} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,padding: 20,},
});export default Flex;

image-20231102165815456

如果将上述 flexDirection: “column” 改为 flexDirection: "row"的话,效果图如下:

横向布局

3.2 Flex Direction

在组件的style中指定flexDirection可以决定布局的主轴。子元素是应该沿着**水平轴(row)方向排列,还是沿着竖直轴(column)方向排列呢?默认值是竖直轴(column)**方向。

  • column默认值):将子元素从上到下对齐。如果启用换行,则下一行将从容器顶部的第一个项目右侧开始。
  • row:将子元素从左到右对齐。如果启用换行,则下一行将在容器左侧的第一个项目下方开始。
  • column-reverse:将子元素从底部向上对齐。如果启用换行,则下一行将从容器底部的第一个项目右侧开始。
  • row-reverse:将子元素从右到左对齐。如果启用换行,则下一行将在容器右侧的第一个项目下方开始。
import React, {useState} from 'react';
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';const FlexDirectionBasics = () => {const [flexDirection, setFlexDirection] = useState('column');return (<PreviewLayoutlabel="flexDirection"values={['column', 'row', 'row-reverse', 'column-reverse']}selectedValue={flexDirection}setSelectedValue={setFlexDirection}><View style={[styles.box, {backgroundColor: 'powderblue'}]} /><View style={[styles.box, {backgroundColor: 'skyblue'}]} /><View style={[styles.box, {backgroundColor: 'steelblue'}]} /></PreviewLayout>);
};const PreviewLayout = ({label,children,values,selectedValue,setSelectedValue,
}) => (<View style={{padding: 10, flex: 1}}><Text style={styles.label}>{label}</Text><View style={styles.row}>{values.map(value => (<TouchableOpacitykey={value}onPress={() => setSelectedValue(value)}style={[styles.button, selectedValue === value && styles.selected]}><Textstyle={[styles.buttonLabel,selectedValue === value && styles.selectedLabel,]}>{value}</Text></TouchableOpacity>))}</View><View style={[styles.container, {[label]: selectedValue}]}>{children}</View></View>
);const styles = StyleSheet.create({container: {flex: 1,marginTop: 8,backgroundColor: 'aliceblue',},box: {width: 50,height: 50,},row: {flexDirection: 'row',flexWrap: 'wrap',},button: {paddingHorizontal: 8,paddingVertical: 6,borderRadius: 4,backgroundColor: 'oldlace',alignSelf: 'flex-start',marginHorizontal: '1%',marginBottom: 6,minWidth: '48%',textAlign: 'center',},selected: {backgroundColor: 'coral',borderWidth: 0,},buttonLabel: {fontSize: 12,fontWeight: '500',color: 'coral',},selectedLabel: {color: 'white',},label: {textAlign: 'center',marginBottom: 10,fontSize: 24,},
});export default FlexDirectionBasics;

解析一下:

第5行:设置flexDirection这个属性默认值为column

第8行和第16行:调用PreviewLayout这个组件

第9~12行:分别给PreviewLayout传参

  • label=“flexDirection” 一个字符串
  • values={[‘column’, ‘row’, ‘row-reverse’, ‘column-reverse’]} 一个字符串数组
  • selectedValue={flexDirection} selectedValue属性值就是flexDirection变量的值
  • setSelectedValue={setflexDirection} setSelectedValue属性值调用setflexDirection方法,相当于会改变flexDirection的值

第13~15行:声明三个正方形的view,宽和高分别为50

第20~26行:声明PreviewLayout组件

第27和46行:声明整个父容器,距离边距是10,flex为1代表占据整个边距是10的容器

第28行:声明一个Text的组件,样式是styles.label,居中显示距离下面组件的间距是10,字体大小是24。文字内容是21行传参过来的label,也就是第九行的"flexDirection"

label: {textAlign: 'center',marginBottom: 10,fontSize: 24,
}

第29行和44行:声明要展示的第二部分view

第30行:对传下来的values数组,遍历里面的每个元素

第31行和第42行:声明一个TouchableOpacity系统组件

第32行:声明TouchableOpacity组件的key为values数组里每个元素的值

第33行:声明TouchableOpacity组件的按压下去触发的动作会调用setSelectedValue(value)方法,而setSelectedValue(value)实际上就是改变flexDirection这个变量的值

第34行:声明TouchableOpacity组件的style属性为styles.button的属性,以及如果selectedValue的值等于遍历当前values数组的值,那么就会再拼接上styles.selected属性的值,也就是下面两个css的值。(遍历到的那个组件的元素css样式是下面两个css样式组合起来的,否则就只是button一个css样式的)

button: {paddingHorizontal: 8,paddingVertical: 6,borderRadius: 4,backgroundColor: 'oldlace',alignSelf: 'flex-start',marginHorizontal: '1%',marginBottom: 6,minWidth: '48%',textAlign: 'center',
},
selected: {backgroundColor: 'coral',borderWidth: 0,
},

第35行和第41行:在TouchableOpacity组件里声明一个Text组件

第36~39行:如果被选中,声明Text的样式为下面两个css的样式;否则声明的Text样式为buttonLabel的css样式

buttonLabel: {fontSize: 12,fontWeight: '500',color: 'coral',
},
selectedLabel: {color: 'white',
}

第45行:声明在PreviewLayout组件里的子组件,也就是13到15行里的组件,对应的样式是container,其中每个组件里的flexDirection属性就是当前selectedValue的属性值

<View style={[styles.box, {backgroundColor: 'powderblue'}]} />
<View style={[styles.box, {backgroundColor: 'skyblue'}]} />
<View style={[styles.box, {backgroundColor: 'steelblue'}]} />

上述代码运行如下:

测试FlexDirection

相关文章:

React Native 样式及其布局

React Native 样式及其布局 参考 https://reactnative.cn/docs/flexbox 一、样式 在 React Native 中&#xff0c;你并不需要学习什么特殊的语法来定义样式。我们仍然是使用 JavaScript 来写样式。所有的核心组件都接受名为style的属性。这些样式名基本上是遵循了 web 上的 …...

基于51单片机的智能指纹考勤系统设计

**单片机设计介绍&#xff0c;1661【毕设课设】基于51单片机的智能指纹考勤系统设计-原理图-PCB-程序-报告 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于51单片机的智能指纹考勤系统是一种利用51单片机作为主控芯片&#x…...

I/O性能优化——这一篇就足够啦

背景 继上一篇CPU性能优化文章 &#xff0c;本次向大家分享关于I/O性能优化的分析套路以及常见措施。后续还有关于内存及网络优化的篇章。 基本概念 对于I/O我们先了解几个概念&#xff0c;文件系统&#xff0c;磁盘&#xff0c;文件。 磁盘 磁盘为系统提供了最基本的持久化存…...

【蓝桥杯选拔赛真题44】python小蓝晨跑 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析

目录 python小蓝晨跑 一、题目要求 1、编程实现 2、输入输出 二、算法分析...

摩托车商家做展示预约小程序的作用

摩托车与电动车是人们短距离出行的主要工具&#xff0c;而其使用寿命一般是3年左右及以上、一家可能有多个&#xff0c;市场人群庞大且复购属性强&#xff0c;所以其经营商家也非常多。 如今互联网深入&#xff0c;在品牌宣传、客户获取、信息承载、营销等方面需要车辆经营商家…...

数据库实验:SQL的多表数据查询

目录 实验目的实验内容实验要求实验过程实验代码结果示意 书接上文&#xff0c;但是感觉之前的形式不太好用&#xff0c;至少不是很方便观看&#xff0c;所以这篇尝试改变一下写法&#xff0c;希望可以提升一些观感 实验目的 (1) 掌握RDBMS的数据多表查询功能 (2) 掌握SQL语言…...

【使用Python编写游戏辅助工具】第一篇:概述

引言 欢迎阅读本系列文章&#xff0c;本系列将带领读者朋友们使用Python来实现一个简单而有趣的游戏辅助工具。 写这个系列的缘由源自笔者玩了一款游戏。正巧&#xff0c;笔者对Python编程算是有一定的熟悉&#xff0c;且Python语言具备实现各种有趣功能的能力&#xff0c;因…...

Android与IOS渲染流程对比

目录 Android CPU计算图元信息 GPU干预 几何阶段等后处理 Android APP通过WindowManager统一提供所有Surface的缓冲区【不管是SurfaceView还是普通的布局流程都会将数据提交到Surface的BufferQuene中】 Java中的Surface是null&#xff0c;最终都是由Native层的Surface处理。…...

正则表达式以及 pattern 的撰写方式

正则表达式的撰写方法 在Python中,可以使用re模块来进行正则表达式的撰写和匹配。下面是一个基本的正则表达式撰写方法示例: 导入re模块: python import re定义正则表达式模式: python pattern = r正则表达式其中,r表示原始字符串,可以避免转义字符的问题。 使用re模…...

K8s Error: ImagePullBackOff 故障排除

Error: ImagePullBackOff 故障排除 1. 起因 起因是要在一组k8s环境下做个Prometheus的测试,当时虚拟机用完直接暂停了. 启动完master和node节点后重启了这些节点. 当检查dashboard时候发现Pod处于ImagePullBackOff状态,使用命令查看详细情况 kubectl describe pods -n kuber…...

爬虫之爬虫介绍、requests模块、携带请求参数、url 编码和解码、携带请求头

爬虫介绍 爬虫是什么&#xff1f; 网页蜘蛛&#xff0c;网络机器人&#xff0c;spider在互联网中 通过 程序 自动的抓取数据 的过程根上&#xff1a;使用程序 模拟发送http请求 ⇢ \dashrightarrow ⇢ 得到http响应 ⇢ \dashrightarrow ⇢ 把响应的数据解析出来 ⇢ \dashr…...

pytorch笔记:split

torch.split 是 PyTorch 中的一个函数&#xff0c;用于将张量按指定的大小或张量数量进行分割 1 基本使用方法 torch.split(tensor, split_size_or_sections, dim0)tensor要分割的输入张量split_size_or_sections以是整数或整数列表。 如果是整数&#xff0c;那么它表示每个分…...

K8S运维 解决openjdk:8-jdk-alpine镜像时区和字体问题

目录 一、问题 二、解决 三、完整代码 一、问题 由于项目的Dockerfile中使用openjdk:8-jdk-alpine作为基础镜像来部署服务&#xff0c;此镜像存在一定问题&#xff0c;例如时差8小时问题&#xff0c;或是由于字体问题导致导出excel文件&#xff0c;图片处理内容为空等。 二…...

Kubectl详解(陈述式、声明式)

目录 1、陈述式资源管理方法 1.1 基本信息查看 1.2 项目的生命周期&#xff1a;创建-->发布-->更新-->回滚-->删除 1.3 金丝雀发布&#xff08;Canary Release&#xff09; 2、声明式管理方法 1、陈述式资源管理方法 1.kubernetes 集群管理集群资源的唯一入口是…...

使用HttpClient库的爬虫程序

使用HttpClient库的爬虫程序&#xff0c;该爬虫使用C#来抓取内容。 using System; using System.Net.Http; using System.Threading.Tasks; ​ namespace CrawlerProgram {class Program{static void Main(string[] args){// 创建HttpClient对象using (HttpClient client new…...

VSIX:C#项目 重命名所有标识符(Visual Studio扩展开发)

出于某种目的&#xff08;合法的&#xff0c;真的合法的&#xff0c;合同上明确指出可以这样做&#xff09;&#xff0c;我准备了一个重命名所有标识符的VS扩展&#xff0c;用来把一个C#库改头换面&#xff0c;在简单的测试项目上工作很满意&#xff0c;所有标识符都被准确替换…...

【CSDN 每日一练 ★★☆】【动态规划】最小路径和

【CSDN 每日一练 ★★☆】【动态规划】最小路径和 动态规划 题目 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 示例 示例 1&#x…...

前端学习之webpack的使用

概述 webpack是一个流行的前端项目构建工具&#xff08;打包工具&#xff09;&#xff0c;可以解决当前web开发中所面临的问题。 webpack提供了友好的模块化支持&#xff0c;以及代码压缩混淆、处理js兼容问题、性能优化等强大的功能&#xff0c;从而让程序员把工作重心放到具…...

【java学习—十一】泛型(1)

文章目录 1. 为什么要有泛型Generic2. 泛型怎么用2.1. 泛型类2.2. 泛型接口2.3. 泛型方法 3. 泛型通配符3.1. 通配符3.2. 有限制的通配符 1. 为什么要有泛型Generic 泛型&#xff0c;JDK1.5新加入的&#xff0c;解决数据类型的安全性问题&#xff0c;其主要原理是在类声明时通过…...

CN考研真题知识点二轮归纳(4)

持续更新&#xff0c;上期目录&#xff1a; CN考研真题知识点二轮归纳&#xff08;4&#xff09;https://blog.csdn.net/jsl123x/article/details/134135134?spm1001.2014.3001.5501 1.既可以扩展网段又是二层的设备 网段一般指一个计算机网络中使用同一物理层设备&#xff…...

ROS学习笔记(4):ROS架构和通讯机制

前提 前4篇文章以及帮助大家快速入门ROS了&#xff0c;而从第5篇开始我们会更加注重知识积累。同时我强烈建议配合B站大学的视频一起服用。 1.ROS架构三层次&#xff1a; 1.基于Linux系统的OS层&#xff1b; 2.实现ROS核心通信机制以及众多机器人开发库的中间层&#xff1b…...

深度新闻稿件怎么写?新闻稿怎么写得有深度?

深度新闻稿件&#xff0c;顾名思义&#xff0c;是对新闻事件进行深入挖掘和分析的稿件。它不仅仅是对事件的简单报道&#xff0c;更注重对事件背后的社会现象、原因、影响等方面进行深度剖析&#xff0c;从而使读者能够全面、深入地了解事件。这种稿件要求作者具备较高的新闻敏…...

百度智能云千帆大模型平台黑客马拉松报名开启!

比赛简介 创造是生成式 AI 的核心。无论是智能导购带来的线上购物体验升级&#xff0c;还是主图生成带来的素材生产效率提升&#xff0c;又或是游戏场景的快速设置、智能 NPC 的全新交互、数字广告的精准推荐和个性化定制&#xff0c;亦或者是为学生提供更符合真实的口语练习环…...

数据库 | 看这一篇就够了!最全MySQL数据库知识框架!

大家好&#xff01; 作为一名程序员&#xff0c;每天和各种各样的“数据库”打交道&#xff0c;已经成为我们的日常。当然&#xff0c;立志成为一名超级架构师的我&#xff0c;肯定要精通这项技能。咳咳&#xff01;不过饭还是要一口一口吃的&#xff0c;“数据库”这个内容实在…...

Android 控件背景实现发光效果

主要实现的那种光晕效果&#xff1a;中间亮&#xff0c;四周逐渐变淡的。 这边有三种发光效果&#xff0c;先上效果图。 第一种、圆形发光体 实现代码&#xff1a;新建shape_light.xml&#xff0c;导入以下代码。使用时&#xff0c;直接给view设置为background。 <?xml …...

安全狗亮相厦门市工信领域数据安全宣贯培训会

10月31日&#xff0c;厦门市工业和信息化局&#xff08;市大数据管理局&#xff09;顺利举办厦门市工信领域数据安全宣贯培训。 作为国内云原生安全领导厂商&#xff0c;安全狗以厦门市工业领域数据安全管理支撑单位身份受邀出席此次会议。 据悉&#xff0c;此次活动旨在贯彻…...

最长回文子串

问题 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 示例 1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab" 解释&#xff1a;"aba" 同…...

从瀑布模式到水母模式:ChatGPT引领软件研发的革新之路

ChatGPT引领软件研发的革新之路 概述操作建议本书优势 内容简介作者简介专家推荐读者对象目录直播预告写在末尾&#xff1a; 主页传送门&#xff1a;&#x1f4c0; 传送 概述 计算机技术的发展和互联网的普及&#xff0c;使信息处理和传输变得更加高效&#xff0c;极大地改变了…...

一种使用wireshark快速分析抓包文件amr音频流的思路方法

解决方案&#xff1a; 1. 使用wireshark过滤amr,并导出原始数据文件&#xff1b; 2.使用ue的二进制编辑模式&#xff0c;编辑该文件&#xff0c;添加amr头&#xff0c;6个字节数据“#!AMR”&#xff0c;字节数据为 23 21 41 4D 52 0A 3.修正格式&#xff1a;通过抓包发现&#…...

银河麒麟x86版、银河麒麟arm版操作系统编译zlmediakit

脚本 # 安装依赖 gcc-c.x86_64 这个不加的话会有问题 sudo yum -y install gcc gcc-c libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg git openssl-devel gcc-c.x86_64mkdir -p /home/zenglg cd /home/zenglg git clone --depth 1 https://gitee.com/xia-chu…...