【React Native】布局文件-底部TabBar

布局文件-底部tabBar

内容配置

export default function Layout() {return (<Tabs />);
}

默认会将布局文件是将与它在同一个目录的所有文件,包括下级目录的文件,全都配置成Tab了。:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这样做显然不对,正确的做法是

  • app目录里新建一个(tabs)文件夹,注意了,名字上有一对小括号。
  • 里面新建一个_layout.js布局文件,这里就专门放TabBar配置。
  • 然后将index.js,挪动到(tabs)里面。
  • (tabs)里,再新建一个videos.jsusers.js文件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

app/_layout.js

import { Stack } from 'expo-router';export default function Layout() {return (<StackscreenOptions={{title: '',                      // 默认标题为空headerTitleAlign: 'center',     // 安卓标题栏居中animation: 'slide_from_right',  // 安卓使用左右切屏headerTintColor: '#1f99b0',     // 导航栏中文字、按钮、图标的颜色headerTitleStyle: {             // 标题组件的样式fontWeight: '400',color: '#2A2929',fontSize: 16,},headerBackButtonDisplayMode: 'minimal', // 设置返回按钮只显示箭头,不显示文字}}>{/* Tabs */}<Stack.Screen name="(tabs)" options={{ headerShown: false }} />{/* Cards */}<Stack.Screen name="articles/index" options={{ title: '通知' }} /><Stack.Screen name="settings/index" options={{ title: '设置' }} /><Stack.Screen name="courses/[id]" options={{ title: '课程详情' }} /><Stack.Screen name="search/index" options={{ title: '搜索' }} /></Stack>);
}
  • TabBar的配置:

    • 注意这里有个headerShown,这是因为TabBar也会自带一个导航栏。
    • 如果不隐藏,它会和Stack的导航栏同时出现,这就会出来两个导航栏了。
  • 底下给各个页面都添加上了title

  • Stack里页面是有两种形式的:

    • 这种页面左右滑动跳转的就叫Cards
    • 另一种页面从屏幕底部弹出的,叫做模态(Modal)

app/(tabs)/_layout.js

import { Link, Tabs } from 'expo-router'
import { Image } from 'expo-image'
import { SimpleLineIcons } from '@expo/vector-icons'
import { StyleSheet, TouchableOpacity } from 'react-native'/*** 导航栏 Logo 组件*/
function LogoTitle() {return <Image style={style.logo} contentFit="contain" source={require('../../assets/logo-light.png')}/>
}/*** 导航栏按钮组件* @param props*/
function HeaderButton({ href, ...rest }) {return (<Link href={href} asChild><TouchableOpacity><SimpleLineIcons size={20} color="#1f99b0" {...rest} /></TouchableOpacity></Link>)
}export default function TabsLayout() {return (<TabsscreenOptions={{headerTitleAlign: 'center',       // 安卓标题栏居中headerTitle: props => <LogoTitle {...props} />,headerLeft: () => <HeaderButton name="bell" href="/articles" style={style.headerLeft} />,headerRight: () => (<><HeaderButton name="magnifier" href="/search" style={style.headerRight} /><HeaderButton name="options" href="/settings" style={style.headerRight} /></>),}}><Tabs.Screenname="index"options={{ title: '首页' }}/><Tabs.Screenname="videos"options={{ title: '视频课程' }}/><Tabs.Screenname="users"options={{ title: '我的' }}/></Tabs>);
}const style = StyleSheet.create({logo: {width: 130,height: 30,},headerLeft: {marginLeft: 15,},headerRight: {marginRight: 15,},
});

(tabs)目录,专门用来放各个Tab页。名字上的这个小括号,叫做路由分组

  • 利用它,将一些相关的文件,放在一起。

  • 这种带小括号的目录名,在URL里不计算路径!

    • index.jsURL,依然还是/index,就像还在app目录里一样,它依然还是首页
    • videos.js文件的URL,其实是/videos,而不是/(tabs)/videos,同理。
  • 底下的和刚才不同,刚才的布局文件里使用的是StackStack.Screen。这里要用TabsTabs.Screen

  • 然后将顶部的按钮,配置到了最外层的screenOptions里,这样所有的Tab页在导航栏上,都会有Logo和按钮。

  • Tab页,是可以随意跳转到非Tab页的。从哪里都能跳过去,它就属于共享路由。

  • 一个项目里,也可以有多个布局文件,布局文件只对和它同级或下级文件生效。

图标和样式

在上面的基础上增加图标和样式:

    /*** TabBar 图标组件* @param props*/function TabBarIcon(props) {return <SimpleLineIcons size={25} {...props} />;}<Tabs . Screenname="users"options={{title: "我的",tabBarIcon: ({ color }) => <TabBarIcon name="user" color={color} />,}}/><TabsscreenOptions={{headerTitleAlign: "center", // 安卓标题栏居中headerTitle: (props) => <LogoTitle {...props} />,headerLeft: () => (<HeaderButton name="bell" href="/articles" style={style.headerLeft} />),headerRight: () => (<><HeaderButtonname="magnifier"href="/search"style={style.headerRight}/><HeaderButtonname="options"href="/settings"style={style.headerRight}/></>),tabBarActiveTintColor: "#1f99b0", // 设置 TabBar 选中项的颜色tabBarStyle: {height: 80, // 设置 TabBar 的高度},tabBarLabelStyle: {marginTop: 4, // 设置 TabBar 文字与图标之间的间距},}}>

完整代码:

import { Link, Tabs } from "expo-router";
import { Image } from "expo-image";
import { SimpleLineIcons } from "@expo/vector-icons";
import { StyleSheet, TouchableOpacity } from "react-native";/*** 导航栏 Logo 组件*/
function LogoTitle() {return (<Imagestyle={style.logo}contentFit="contain"source={require("../../assets/logo-light.png")}/>);
}/*** TabBar 图标组件* @param props*/
function TabBarIcon(props) {return <SimpleLineIcons size={25} {...props} />;
}/*** 导航栏按钮组件* @param props*/
function HeaderButton({ href, ...rest }) {return (<Link href={href} asChild><TouchableOpacity><SimpleLineIcons size={20} color="#1f99b0" {...rest} /></TouchableOpacity></Link>);
}export default function TabsLayout() {return (<TabsscreenOptions={{headerTitleAlign: "center", // 安卓标题栏居中headerTitle: (props) => <LogoTitle {...props} />,headerLeft: () => (<HeaderButton name="bell" href="/articles" style={style.headerLeft} />),headerRight: () => (<><HeaderButtonname="magnifier"href="/search"style={style.headerRight}/><HeaderButtonname="options"href="/settings"style={style.headerRight}/></>),tabBarActiveTintColor: "#1f99b0", // 设置 TabBar 选中项的颜色tabBarStyle: {height: 80, // 设置 TabBar 的高度},tabBarLabelStyle: {marginTop: 4, // 设置 TabBar 文字与图标之间的间距},}}><Tabs.Screenname="index"options={{title: "发现",tabBarIcon: ({ color }) => (<TabBarIcon name="compass" color={color} />),}}/><Tabs.Screenname="videos"options={{title: "视频课程",tabBarIcon: ({ color }) => (<TabBarIcon name="camrecorder" color={color} />),}}/><Tabs.Screenname="users"options={{title: "我的",tabBarIcon: ({ color }) => <TabBarIcon name="user" color={color} />,}}/></Tabs>);
}const style = StyleSheet.create({logo: {width: 130,height: 30,},headerLeft: {marginLeft: 15,},headerRight: {marginRight: 15,},
});

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89179.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89179.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CompareFace使用

CompareFace 使用 CompareFace 有三种服务&#xff0c;分别是人脸识别&#xff08;RECOGNITION&#xff09;、人脸验证&#xff08;VERIFICATION&#xff09;、人脸检测&#xff08;DETECTION&#xff09;。 人脸识别其实就是人脸身份识别(每张照片只有一个人脸)&#xff0c;…

APP测试之Monkey压力测试

&#xff08;一&#xff09;Monkey简介 Monkey意指猴子&#xff0c;顽皮淘气。所以Monkey测试&#xff0c;顾名思义也就像猴子一样在软件上乱敲按键&#xff0c;猴子什么都不懂&#xff0c;就爱捣乱。 Monkey 是 Android SDK 自带的命令行工具&#xff0c;它通过向系统发送伪…

时序大模型为时序数据库带来的变革与机遇

时序数据&#xff08;Time Series Data&#xff09;作为记录系统状态随时间变化的重要数据类型&#xff0c;在物联网、金融交易、工业监控等领域呈爆炸式增长。传统时序数据库专注于高效存储和查询时序数据&#xff0c;而时序大模型&#xff08;Time Series Foundation Models&…

深入核心:理解Spring Boot的三大基石:起步依赖、自动配置与内嵌容器

深入核心&#xff1a;理解Spring Boot的三大基石&#xff1a;起步依赖、自动配置与内嵌容器 摘要&#xff1a;在上一章&#xff0c;我们领略了Spring Boot带来的革命性开发体验。但魔法的背后&#xff0c;必有其科学的支撑。本章将带你深入Spring Boot的内核&#xff0c;系统性…

达梦数据库配置兼容MySQL

前言 作为一名数据库管理员或开发者&#xff0c;当项目需要从MySQL迁移到达梦数据库时&#xff0c;最关心的莫过于兼容性问题。达梦作为国产数据库的佼佼者&#xff0c;提供了良好的MySQL兼容模式&#xff0c;今天我就来分享一下如何配置达梦数据库以实现对MySQL的兼容。 一、为…

js与vue基础学习

vue创建项目 安装node安装node、npm、cnpm node -v npm -v #npm服务器位置处于国外&#xff0c;下载包的速度会比较缓慢。阿里为国内用户提供的cnpm&#xff0c;他是npm的镜像&#xff0c;下载第三方包时&#xff0c;们完全可以使用cnpm来替代npm。 cnpm -v在node中执行JavaScr…

【开源.NET】一个 .NET 开源美观、灵活易用、功能强大的图表库

文章目录一、项目介绍二、适用场景三、功能模块四、功能特点五、效果展示六、开源地址一、项目介绍 LiveCharts2 是一个开源、简单、灵活、交互式且功能强大的 .NET 图表库。LiveCharts2 现在几乎可以在任何地方运行&#xff1a;Maui、Uno Platform、Blazor-wasm、WPF、WinFor…

使用Whistle自定义接口返回内容:Mock流式JSON数据全解析

一.mock接口返回数据流程 定位目标接口 在Whistle的Network面板中找到需要Mock的接口&#xff0c;右键点击请求信息&#xff0c;选择COPY -> URL复制完整URL&#xff0c;确保URL路径精确到具体接口。准备Mock数据 点击对应接口&#xff0c;在右侧面板切换到response标签页&a…

【前端】富文本编辑器插件 wangEditor 5 基本使用(Vue2)

https://www.wangeditor.com/v5 一、安装 首先安装editor yarn add wangeditor/editor # 或者 npm install wangeditor/editor --save安装Vue2组件 yarn add wangeditor/editor-for-vue # 或者 npm install wangeditor/editor-for-vue --save或者Vue3 yarn add wangeditor/…

自适应哈希索引 和 日志缓冲区

目录 1. 自适应哈希索引在内存中的位置 2. 自适应哈希索引的作用 3. 为什么要创建自适应哈希索引 4. 适应哈希索引的Key -Value如何设置&#xff1f; 5. 日志缓冲区在内存中的位置 6. 日志缓冲区的作用 7. 日志不通过LogBuffer直接写入磁盘不行吗&#xff1f; 1. 自适应哈…

中国旅行社协会在京召开“文旅人工智能应用研讨会”,助力文旅创新发展

7月15日&#xff0c;由中国旅行社协会数字经济专业委员会和在线旅行服务商分会联合主办的“人工智能技术在文旅产业中的应用”研讨会在北京举行。中国旅行社协会副会长、秘书长孙桂珍出席并致辞&#xff0c;中国工程院外籍院士、具身智能机器人专家张建伟、北京第二外国语学院旅…

Linux之Zabbix分布式监控篇(一)

一、概念和特点概念Zabbix是一款开源、免费的监控软件 主要用于7*24*365实时监控网络设置&#xff0c;操作系统&#xff0c;应用程序&#xff0c;网络带宽等资源的运行状态&#xff0c;并且一旦发生异常能够第一时间个SA管理员发送报警信息特点Zabbix是c/s结构&#xff0c;有c…

ZYNQ千兆光通信实战:Tri Mode Ethernet MAC深度解析

—— 从硬件设计到Linux驱动的光通信创新实践** 当ZYNQ遇上光通信 在工业控制、医疗成像和航空航天等领域,抗干扰、长距离传输的光通信技术至关重要。Xilinx ZYNQ-7000系列凭借ARM+FPGA的架构,结合Tri Mode Ethernet MAC (TEMAC) 核心,为千兆光通信提供了完美解决方案。本文…

求不重叠区间总和最大值

例题链接&#xff1a;1051-习题-数学考试_2021秋季算法入门班第一章习题&#xff1a;模拟、枚举、贪心 来源&#xff1a;牛客网 时间限制&#xff1a;C/C/Rust/Pascal 1秒&#xff0c;其他语言2秒 空间限制&#xff1a;C/C/Rust/Pascal 32 M&#xff0c;其他语言64 M 64bit …

【Golang】GORM - GEN工具 快速开始

文章目录建项目建库建表main.gouser.gocompany.go生成效果&#xff08;更进一步&#xff09;自定义dynamic SQL实践官方地址&#xff1a;https://gorm.io/zh_CN/gen/index.html 以mysql为例 建项目 go mod init 项目名称 go mod tidy建库建表 建数据库demo&#xff0c;正常…

飞书 “打破” AI 与协同办公的「黑箱」

文 | 智能相对论作者 | 陈泊丞在协同办公领域&#xff0c;自从有了AI&#xff0c;微软、钉钉、Google Workspace、Salesforce、企业微信、飞书等厂商都试图通过深度整合AI技术&#xff0c;从智能会议、内容创作、数据管理等场景重构办公范式。微软通过Microsoft 365 Copilot将A…

leetcode:674. 最长连续递增序列[动归]

学习要点 练习动归注意不要马虎 题目链接 674. 最长连续递增序列 - 力扣&#xff08;LeetCode&#xff09; 题目描述 解法&#xff1a;动归 class Solution { public:int findLengthOfLCIS(vector<int>& nums) {int n nums.size();if(nums.size() < 1) …

【html常见页面布局】

考拉商城界面效果htmlcss效果 html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</ti…

摩尔线程MUSA架构深度调优指南:从CUDA到MUSA的显存访问模式重构原则

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;H卡级别算力&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生专属优惠。 当国产GPU面临生态壁垒&#xff0c;显存访问效率成为性能突破的关键战场。本文将深入揭示摩尔…

2025江苏省信息安全管理与评估赛项二三阶段任务书

任务 3 网络安全事件响应、数字取证调查、网络安全渗透任务3.1&#xff1a;网络安全事件响应&#xff08;100分&#xff09;X集团的一台存储关键信息的服务器遭受到了黑客的攻击&#xff0c;现在需要你对该服务器进行应急排查&#xff0c;该服务器的系统目录被上传恶意文件&…