flutter:BottomNavigationBar和TabBar
区别
BottomNavigationBarr和TabBar都是用于创建导航栏的组件,但它们有一些区别。
-
位置不同:
BottomNavigationBar通常位于屏幕底部,用于主要导航;而TabBar通常位于屏幕顶部或底部,用于切换不同的视图或页面。 -
样式不同:
BottomNavigationBar是一个水平的导航栏,通常包含固定数量的图标和标签。它提供了固定的样式,并且可以自动处理选中和未选中状态的切换。TabBar可以水平或垂直显示,通常用于展示多个选项卡。它提供了更多的自定义选项,比如可以设置自定义的标签样式、背景色等。 -
功能不同:
BottomNavigationBar通常用于在不同的主页面之间进行导航,每个图标对应一个页面。它的功能相对简单,适用于主要导航。TabBar用于切换不同的视图或页面,并且可以与TabBarView一起使用来展示与每个选项卡对应的内容。它在应用程序中的使用场景更加广泛,适用于切换和展示多个相关页面或功能。
总之,BottomNavigationBar适用于简单的主导航,TabBar适用于更复杂的页面切换和内容展示。
示例:来源于qq阅读
BottomNavigationBar

TabBar

BottomNavigationBar
BottomNavigationBar是Flutter中用于创建底部导航栏的组件。它通常与TabBarView一起使用,用于在不同的选项卡之间切换内容。
BottomNavigationBar有一个items属性,其中可以定义导航栏的每个选项卡。每个选项卡都可以包含一个图标和一个文本标签。
class SwitcherContainer extends StatefulWidget {const SwitcherContainer({Key? key}) : super(key: key);SwitcherContainerState createState() => SwitcherContainerState();
}class SwitcherContainerState extends State<SwitcherContainer> {String name = '首页';List<String> nameList = ['首页', '书籍', '我的'];// 激活项int _currentIndex = 0;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('导航'),),body: Center(child: Text(name),),bottomNavigationBar: BottomNavigationBar(items: const [BottomNavigationBarItem(label: '首页', icon: Icon(Icons.home)),BottomNavigationBarItem(label: '书籍', icon: Icon(Icons.book)),BottomNavigationBarItem(label: '我的', icon: Icon(Icons.perm_identity)),],currentIndex: _currentIndex,// 激活颜色selectedItemColor: Colors.orange,// 点击事件onTap: (index) {setState(() {_currentIndex = index;name = nameList[index];});},),);}
}

如果没有特殊需求的话,使用系统提供的就可以。如果想要点不太一样的可以看一下下面这两个库:
- curved_navigation_bar
- google_nav_bar
curved_navigation_bar
一个易于实现曲面导航条
官方地址
https://pub-web.flutter-io.cn/packages/curved_navigation_bar
安装
flutter pub add curved_navigation_bar
简单使用
class SwitcherContainerState extends State<SwitcherContainer> {String name = '首页';List<String> nameList = ['首页', '书籍', '我的'];// 激活项int _currentIndex = 0;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('导航'),),body: Stack(children: [Container(color: Colors.blueAccent,width: MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height,child: null,),Container(color: Colors.white,width: MediaQuery.of(context).size.width,height: MediaQuery.of(context).size.height - 150,child: Text(name),)],),bottomNavigationBar: CurvedNavigationBar(items: const [Icon(Icons.home),Icon(Icons.book),Icon(Icons.perm_identity)],height: 60,backgroundColor: Colors.blueAccent,//激活项index: _currentIndex,// 点击事件onTap: (index) {setState(() {_currentIndex = index;name = nameList[index];});},),);}
}

这个最好像我上面那样再调整一下,不然有点奇怪,比如:

bottom_navy_bar
一个美丽而生动的底部导航。导航栏使用您当前的主题,但您可以自由自定义
官方地址
https://pub-web.flutter-io.cn/packages/bottom_navy_bar
安装
flutter pub add bottom_navy_bar
简单使用
class SwitcherContainerState extends State<SwitcherContainer> {String name = '首页';List<String> nameList = ['首页', '书籍', '我的'];// 激活项int _currentIndex = 0;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('导航'),),body: Center(child: Text(name),),bottomNavigationBar: BottomNavyBar(// 当前选中项selectedIndex: _currentIndex,// 列表items: [BottomNavyBarItem(textAlign: TextAlign.center,icon: const Icon(Icons.home),title: const Text("首页")),BottomNavyBarItem(textAlign: TextAlign.center,icon: const Icon(Icons.book),title: const Text("书架")),BottomNavyBarItem(textAlign: TextAlign.center,icon: const Icon(Icons.perm_identity),title: const Text("我的"))],// 选中事件onItemSelected: (index) => setState(() {_currentIndex = index;name = nameList[index];})),);}
}

TabBar
在Flutter中,TabBar是一个常用的小部件,用于创建一个具有选项卡的导航栏。它通常与TabBarView一起使用,以实现在不同选项卡之间切换内容的功能。
TabBar由TabBar和TabBarView两个关键组件组成。
TabBar:TabBar小部件定义了选项卡的外观和交互方式。它可以包含多个选项卡,每个选项卡都由一个Tab对象表示。可以通过设置controller属性来指定与TabBarView关联的TabController,以便在选项卡之间进行切换。
TabBarView:TabBarView``小部件是一个可滚动的容器,用于显示与当前选中选项卡相关联的内容。每个选项卡对应一个子小部件,并且可以通过设置controller属性来与TabBar`关联。
class SwitcherContainer extends StatefulWidget {const SwitcherContainer({Key? key}) : super(key: key);SwitcherContainerState createState() => SwitcherContainerState();
}class SwitcherContainerState extends State<SwitcherContainer>with SingleTickerProviderStateMixin {// 控制器late TabController tabController;void initState() {super.initState();tabController = TabController(length: 3, vsync: this);}void dispose() {super.dispose();// 释放tabController.dispose();}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('TabBar Demo'),bottom: TabBar( // 使用TabBar作为AppBar的bottom属性controller: tabController, // 关联TabControllertabs: const [Tab(text: 'Tab 1'),Tab(text: 'Tab 2'),Tab(text: 'Tab 3'),],),),body: TabBarView( // 使用TabBarView作为bodycontroller: tabController, // 关联TabControllerchildren: const [Center(child: Text('Content of Tab 1')),Center(child: Text('Content of Tab 2')),Center(child: Text('Content of Tab 3')),],),);}
}
注意点:
- 在Flutter中,
TabBar和TabBarView之间的切换通常需要使用动画效果。为了实现这种动画效果,需要使用TickerProvider,它提供了一个Ticker对象,用于生成动画的时间。而SingleTickerProviderStateMixin是一个实现了TickerProvider的混合类。

或者
return Column(children: [TabBar(controller: tabController,indicatorColor: Colors.red, // 设置选中选项卡下方的指示器颜色labelColor: Colors.blue, // 设置选中选项卡的文本颜色unselectedLabelColor: Colors.grey, // 设置未选中选项卡的文本颜色tabs: const [Tab(text: 'Home',),Tab(text: 'Settings',),],),Expanded(child: TabBarView(controller: tabController,children: const [Center(child: Text("Home"),),Center(child: Text("Settings"),)],),),],);

这里推荐一下:tab_indicator_styler,这个库是用来修改指示器样式的
官方地址
https://pub-web.flutter-io.cn/packages/tab_indicator_styler
安装
flutter pub add tab_indicator_styler
基本使用
import 'package:tab_indicator_styler/tab_indicator_styler.dart';
Scaffold(appBar: AppBar(toolbarHeight: 10,bottom: TabBar(// 使用TabBar作为AppBar的bottom属性controller: tabController, // 关联TabControllerindicatorSize: TabBarIndicatorSize.tab, // 设置指示器宽度// 指示器样式indicator: MaterialIndicator(height: 5,topLeftRadius: 8,topRightRadius: 8,horizontalPadding: 50,tabPosition: TabPosition.bottom,color: Colors.white),tabs: const [Tab(text: 'Tab 1'),Tab(text: 'Tab 2'),Tab(text: 'Tab 3'),],),),body: TabBarView(// 使用TabBarView作为bodycontroller: tabController, // 关联TabControllerchildren: const [Center(child: Text('Content of Tab 1')),Center(child: Text('Content of Tab 2')),Center(child: Text('Content of Tab 3')),],),);
注意:MaterialIndicator风格的指示器的宽度必须使用indicatorSize: TabBarIndicatorSize.tab,也就是默认值,否则会报错

indicator: DotIndicator(radius: 5,color: Colors.orange,// 圆点距离文字的间距,正数在下面,负数在上面distanceFromCenter: 20,),

indicator: RectangularIndicator(bottomLeftRadius: 30,bottomRightRadius: 30,topLeftRadius: 30,topRightRadius: 30,),

相关文章:
flutter:BottomNavigationBar和TabBar
区别 BottomNavigationBarr和TabBar都是用于创建导航栏的组件,但它们有一些区别。 位置不同:BottomNavigationBar通常位于屏幕底部,用于主要导航;而TabBar通常位于屏幕顶部或底部,用于切换不同的视图或页面。 样式不…...
【图论】Prim算法
一.介绍 Prim算法是一种用于解决最小生成树问题的贪心算法。最小生成树问题是指在一个连通无向图中找到一个生成树,使得树中所有边的权重之和最小。 Prim算法的基本思想是从一个起始顶点开始,逐步扩展生成树,直到覆盖所有顶点。具体步骤如下…...
第九十二回 在Flutter中解析JSON数据
文章目录 概念介绍解析方法convert库插件工具 示例代码经验总结 我们在上一章回中介绍了"对dio库进行封装"相关的内容,本章回中将介绍 如何在Flutter中解析JSON数据.闲话休提,让我们一起Talk Flutter吧。 概念介绍 我们在前面章回中介绍了通…...
银河麒麟安装mysql数据库(mariadb)-银河麒麟安装JDK-银河麒麟安装nginx(附安装包)
银河麒麟离线全套安装教程(手把手教程) 1.银河麒麟服务器系统安装mysql数据库(mariadb) 2.银河麒麟桌面系统安装mysql数据库(mariadb) 3.银河麒麟服务器系统安装JDK 4.银河麒麟桌面系统安装JDK 5.银河麒麟…...
文件上传
js绕过 打开网页尝试上传一句话木马,发现只能上传图片文件 审计源代码,发现使用一个checkfile函数js对文件类型进行了屏蔽 于是我们修改网页代码,去除返回值的检查函数 checkFile() 上传成功,使用蚁剑连接 连接成功 .htaccess绕…...
tinkerCAD案例:22. Backpack Zipper Pull 背包拉链头
tinkerCAD案例:21. Custom Stamp 定制印章 原文 tinkerCAD案例:22. Backpack Zipper Pull 背包拉链头 Lesson Overview: 课程概述: Now we’re going to make a zipper pull! 现在我们要做一个拉链头! Your backpack, howev…...
Unity 性能优化四:UI耗时函数、资源加载、卸载API
UI耗时函数 1.1 Canvas.SendWillRenderCanvases 这个函数是由于自身UI的更新,产生的耗时 1. 这里更新的是vertex 属性,比如 color、tangent、position、uv,修改recttransform的position、scale,rotation并不会导致顶点属性改变…...
【Linux】用户相关内容
如果命令ll 出现以上信息,UID为具体的数字,代表之前UID为502的用户被删除了。 更改目录或文件所属用户和所属组 在Linux中,创建一个文件时,该文件的拥有者都是创建该文件的用户。 更改所属用户 chown 用户名 文件名/目录名 更…...
基于多场景的考虑虑热网网损的太阳能消纳能力评估研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
【动态规划part10】| 121.买卖股票的最佳时机、122.买卖股票的最佳时机II
目录 🎈LeetCode121. 买卖股票的最佳时机 🎈LeetCode122.买卖股票的最佳时机II 🎈LeetCode121. 买卖股票的最佳时机 链接:121.买卖股票的最佳时机 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定…...
java 页面html常用写法总结
(注意:本文章默认base html中已经引入bootstrap.min.css、style.css等css样式) input :输入标签 <#input required"必填" id"cycle" name"周期" underline"true" style"width:75%" itype&quo…...
阿里云服务器全方位介绍_优势_使用_租用费用详解
阿里云服务器全方位介绍包括云服务器ECS优势、云服务器租用价格、云服务器使用场景及限制说明,阿里云服务器网分享云服务器ECS介绍、个人和企业免费试用、云服务器活动、云服务器ECS规格、优势、功能及应用场景详细你说明: 目录 什么是云服务器ECS&…...
【Kafka】常用操作
1、基本概念 1. 消息: Kafka是一个分布式流处理平台,它通过消息进行数据的传输和存储。消息是Kafka中的基本单元,可以包含任意类型的数据。 2. 生产者(Producer): 生产者负责向Kafka主题发送消息。它将消息…...
【Spring框架】SpringBoot配置文件
目录 配置文件作用application.properties中午乱码问题:配置文件里面的配置类型分类SpringBoot热部署properties基本语法properties配置文件的优缺点:yml配置文件说明yml基本语法配置对象properties VS yml 配置文件作用 整个项⽬中所有重要的数据都是在…...
部署问题集合(十八)Windows环境下使用两个Tomcat
下载Tomcat Tomcat镜像下载地址:https://mirrors.cnnic.cn/apache/tomcat/进入如下地址:zip的是压缩版,exe是安装版 修改第二个Tomcat配置文件 第一步:编辑conf/server.xml文件,修改三个端口,有些版本改…...
数据结构问答8
查找 1. 一些基本概念 关键字:能唯一标识该元素 查找:给定值k,在含n个元素的表中找出关键字==k的元素。找到返回其位置信息,否则返回-1。 动、静态查找表:查找同时对表进行修改(插入、删除等),相应的表为动态,否则为静态。 内、外查找:整个查找过程在内存中进行…...
行为型设计模式之观察者模式【设计模式系列】
系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everythi…...
vue2企业级项目(四)
vue2企业级项目(四) 路由设计,过场动画设计 1、router 项目下载依赖 npm install --save vue-router3.5.3src目录下创建router/index.js import Vue from "vue"; import Router from "vue-router";Vue.use(Router);con…...
(树) 剑指 Offer 26. 树的子结构 ——【Leetcode每日一题】
❓剑指 Offer 26. 树的子结构 难度:中等 输入两棵二叉树 A 和 B,判断 B 是不是 A 的子结构。(约定空树不是任意一个树的子结构) B 是 A 的子结构, 即 A 中有出现和B相同的结构和节点值。 例如: 给定的树 A: 3/ \4 5/ \1 2给定的树 B&…...
Linuxcnc-ethercat从入门到放弃(1)、环境搭建
项目开源网站 LinuxCNChttps://www.linuxcnc.org/当前release版本2.8.4 Downloads (linuxcnc.org)https://www.linuxcnc.org/downloads/可以直接下载安装好linuxcnc的实时debian系统,直接刻盘安装就可以了 安装IgH主站,网上有很多教程可供参考 git clo…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Java并发编程实战 Day 11:并发设计模式
【Java并发编程实战 Day 11】并发设计模式 开篇 这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能…...
VUE3 ref 和 useTemplateRef
使用ref来绑定和获取 页面 <headerNav ref"headerNavRef"></headerNav><div click"showRef" ref"buttonRef">refbutton</div>使用ref方法const后面的命名需要跟页面的ref值一样 const buttonRef ref(buttonRef) cons…...
NLP学习路线图(三十四): 命名实体识别(NER)
一、命名实体识别(NER)是什么? 命名实体识别(Named Entity Recognition, NER)是自然语言处理中的一项关键序列标注任务。其核心目标是从非结构化的文本中自动识别出特定类别的名词性短语,并将其归类到预定义的类别中。 核心目标:找到文本中提到的命名实体,并分类。 典…...
JVM——对象模型:JVM对象的内部机制和存在方式是怎样的?
引入 在Java的编程宇宙中,“Everything is object”是最核心的哲学纲领。当我们写下new Book()这样简单的代码时,JVM正在幕后构建一个复杂而精妙的“数据实体”——对象。这个看似普通的对象,实则是JVM内存管理、类型系统和多态机制的基石。…...
