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里渲染这个组件
最后效果如下图所示:
二、高度与宽度
2.1 固定宽高
组件的高度和宽度决定了其在屏幕上显示的尺寸。
最简单的给组件设定尺寸的方式就是在样式中指定固定的width
和height
。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;
上面代码运行如下:
个人更加推荐使用第二种写法,便于统一编写样式和查看样式。因为通常而言一个文件里会有很多种样式,如果都写在view组件的括号里,视觉效果看起来会很不友好,而且去排查样式问题的时候也不利于去排查到底是哪块的问题。
2.2 弹性(Flex)宽高
在组件样式中使用flex
可以使其在可利用的空间中动态地扩张或收缩。一般而言我们会使用flex:1
来指定某个组件扩张以撑满所有剩余的空间。如果有多个并列的子组件使用了flex:1
,则这些子组件会平分父容器中剩余的空间。如果这些并列的子组件的flex
值不一样,则谁的值更大,谁占据剩余空间的比例就更大(即占据剩余空间的比等于并列组件间flex
值的比)。
组件能够撑满剩余空间的前提是其父容器的尺寸不为零。如果父容器既没有固定的
width
和height
,也没有设定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;
上述代码效果图如下:
如果上述代码的container下的样式flex不为1,设置的是height: 300的话,则效果如下所示:
三、使用Flexbox布局
我们在 React Native 中使用 flexbox 规则来指定某个组件的子元素的布局。Flexbox 可以在不同屏幕尺寸上提供一致的布局结构。
一般来说,使用flexDirection
、alignItems
和 justifyContent
三个样式属性就已经能满足大多数布局需求。
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: 3
。1+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;
如果将上述 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'}]} />
上述代码运行如下:
相关文章:

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

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

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

【蓝桥杯选拔赛真题44】python小蓝晨跑 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析
目录 python小蓝晨跑 一、题目要求 1、编程实现 2、输入输出 二、算法分析...

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

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

【使用Python编写游戏辅助工具】第一篇:概述
引言 欢迎阅读本系列文章,本系列将带领读者朋友们使用Python来实现一个简单而有趣的游戏辅助工具。 写这个系列的缘由源自笔者玩了一款游戏。正巧,笔者对Python编程算是有一定的熟悉,且Python语言具备实现各种有趣功能的能力,因…...
Android与IOS渲染流程对比
目录 Android CPU计算图元信息 GPU干预 几何阶段等后处理 Android APP通过WindowManager统一提供所有Surface的缓冲区【不管是SurfaceView还是普通的布局流程都会将数据提交到Surface的BufferQuene中】 Java中的Surface是null,最终都是由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 编码和解码、携带请求头
爬虫介绍 爬虫是什么? 网页蜘蛛,网络机器人,spider在互联网中 通过 程序 自动的抓取数据 的过程根上:使用程序 模拟发送http请求 ⇢ \dashrightarrow ⇢ 得到http响应 ⇢ \dashrightarrow ⇢ 把响应的数据解析出来 ⇢ \dashr…...
pytorch笔记:split
torch.split 是 PyTorch 中的一个函数,用于将张量按指定的大小或张量数量进行分割 1 基本使用方法 torch.split(tensor, split_size_or_sections, dim0)tensor要分割的输入张量split_size_or_sections以是整数或整数列表。 如果是整数,那么它表示每个分…...
K8S运维 解决openjdk:8-jdk-alpine镜像时区和字体问题
目录 一、问题 二、解决 三、完整代码 一、问题 由于项目的Dockerfile中使用openjdk:8-jdk-alpine作为基础镜像来部署服务,此镜像存在一定问题,例如时差8小时问题,或是由于字体问题导致导出excel文件,图片处理内容为空等。 二…...
Kubectl详解(陈述式、声明式)
目录 1、陈述式资源管理方法 1.1 基本信息查看 1.2 项目的生命周期:创建-->发布-->更新-->回滚-->删除 1.3 金丝雀发布(Canary Release) 2、声明式管理方法 1、陈述式资源管理方法 1.kubernetes 集群管理集群资源的唯一入口是…...

使用HttpClient库的爬虫程序
使用HttpClient库的爬虫程序,该爬虫使用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扩展开发)
出于某种目的(合法的,真的合法的,合同上明确指出可以这样做),我准备了一个重命名所有标识符的VS扩展,用来把一个C#库改头换面,在简单的测试项目上工作很满意,所有标识符都被准确替换…...

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

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

【java学习—十一】泛型(1)
文章目录 1. 为什么要有泛型Generic2. 泛型怎么用2.1. 泛型类2.2. 泛型接口2.3. 泛型方法 3. 泛型通配符3.1. 通配符3.2. 有限制的通配符 1. 为什么要有泛型Generic 泛型,JDK1.5新加入的,解决数据类型的安全性问题,其主要原理是在类声明时通过…...

CN考研真题知识点二轮归纳(4)
持续更新,上期目录: CN考研真题知识点二轮归纳(4)https://blog.csdn.net/jsl123x/article/details/134135134?spm1001.2014.3001.5501 1.既可以扩展网段又是二层的设备 网段一般指一个计算机网络中使用同一物理层设备ÿ…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...