Flutter仿写微信导航栏快速实现页面导航

news2025/1/11 9:04:27

文章目录

  • 前言
  • 使用TabBar实现
    • TabBar介绍
    • TabBar的重要属性
    • 说明
    • TabBarView介绍
    • TabBarView的重要属性
    • TabBar总结
    • TabBar实现底部导航的例子
  • BottomNavigationBar实现
    • BottomNavigationBar介绍
    • BottomNavigationBar实现底部导航栏的例子
  • 总结
    • BottomNavigationBar
    • TabBar
    • 根据实际情况选择

前言

前面介绍了APP顶部导航栏AppBar,今天来介绍下Flutter实现APP底部导航栏。我们以仿写微信的底部导航栏来举例说明。
要实现类似微信底部的导航栏可以使用TabBar或者BottomNavigationBar来实现。下面分别介绍。

使用TabBar实现

TabBar介绍

在Flutter中,TabBar是一个用于创建选项卡式导航的常用组件。它通常与TabBarView一起使用,用于在不同的选项卡之间切换内容。

TabBar的重要属性

下面是TabBar的一些重要属性和功能:

  1. tabs: tabs属性是一个必需的属性,用于指定选项卡的列表。您可以使用Tab小部件创建每个选项卡,并将它们放入tabs列表中。

  2. controller: controller属性用于指定TabController,它负责管理选项卡和视图之间的联动。您可以通过创建一个TabController实例,并将其作为controller属性的值来实现联动。

  3. isScrollable: isScrollable属性用于控制选项卡是否可滚动。当选项卡超出屏幕宽度时,如果设置为true,则可以通过水平滚动查看所有选项卡。

  4. indicatorColor: indicatorColor属性用于设置选项卡下方的指示器的颜色。指示器是一个表示当前选中选项卡的横条。

  5. labelColor 和 unselectedLabelColor: labelColor属性用于设置选中选项卡标签的颜色,而unselectedLabelColor属性用于设置未选中选项卡标签的颜色。

  6. labelStyle 和 unselectedLabelStyle: labelStyle属性用于设置选中选项卡标签的文本样式,而unselectedLabelStyle属性用于设置未选中选项卡标签的文本样式。

  7. onTap: onTap属性是一个回调函数,当用户点击选项卡时会触发该函数。您可以在该回调函数中执行特定的操作,例如更新视图或处理其他逻辑。

说明

一般通过使用TabBar和TabBarView的组合,您可以轻松创建具有选项卡切换功能的界面。TabBar提供了可定制的选项卡导航栏,而TabBarView用于展示与选项卡对应的内容。这使得在Flutter应用程序中实现选项卡式导航变得简单而灵活。

TabBarView介绍

TabBarView是一个用于显示与TabBar选项卡相对应的内容的组件。它与TabBar一起使用,以实现选项卡切换时内容的同步更新。

TabBarView的重要属性

下面是TabBarView的一些重要属性和功能:

  1. children: children属性是一个必需的属性,用于指定与每个选项卡对应的子组件列表。您可以将不同的小部件放入children列表中,以显示不同的内容。

  2. controller: controller属性用于指定TabController,它负责管理选项卡和视图之间的联动。确保将TabController实例作为TabBarView和TabBar的controller属性值保持一致。

  3. physics: physics属性用于指定滚动行为。默认情况下,TabBarView的滚动行为与父级Scrollable组件一致。您可以根据需要设置不同的滚动行为,如NeverScrollableScrollPhysics禁用滚动或BouncingScrollPhysics添加弹性效果。

  4. dragStartBehavior: dragStartBehavior属性控制滚动开始行为。默认情况下,它会根据环境决定是跟随垂直方向还是水平方向进行滚动。您可以通过设置为DragStartBehavior.start或DragStartBehavior.down来强制启动垂直滚动。

  5. physics和dragStartBehavior属性的应用示例:

Copy code
TabBarView(
  controller: _tabController,
  physics: NeverScrollableScrollPhysics(), // 禁用滚动
  dragStartBehavior: DragStartBehavior.down, // 垂直滚动
  children: [
    // 子组件列表
    ...
  ],
)
  1. onPageChanged: onPageChanged属性是一个回调函数,当用户滑动或切换选项卡时,将触发该函数。您可以在此回调函数中执行任何与选项卡切换相关的操作。

TabBar总结

通过将TabBarView与TabBar和TabController结合使用,您可以实现选项卡之间内容的同步切换。当用户切换选项卡时,TabController将相应地更新TabBarView中显示的内容,使用户能够轻松浏览不同的内容。TabBarView为创建选项卡式导航提供了便捷的方式,并且可以根据实际需求进行进一步的定制和样式设置。

TabBar实现底部导航的例子

源码下载

 import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyTabPage(),
    );
  }
}

class MyTabPage extends StatefulWidget {
  
  _MyTabPageState createState() => _MyTabPageState();
}

class _MyTabPageState extends State<MyTabPage> with SingleTickerProviderStateMixin {
  late TabController _tabController;

  
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this); // 3是选项卡数量
  }

  
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('微信'),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          // 第一个选项卡的内容
          Container(
            child: Center(
              child: Text('聊天'),
            ),
          ),
          // 第二个选项卡的内容
          Container(
            child: Center(
              child: Text('群组'),
            ),
          ),
          // 第三个选项卡的内容
          Container(
            child: Center(
              child: Text('个人'),
            ),
          ),
        ],
      ),
      bottomNavigationBar: TabBar(
        controller: _tabController,
        tabs: [
          Tab(icon: Icon(Icons.chat), text: '聊天'),
          Tab(icon: Icon(Icons.group), text: '群组'),
          Tab(icon: Icon(Icons.person), text: '个人'),
        ],
        indicatorColor: Colors.blue, // 选中状态下的指示器颜色
        labelColor: Colors.blue, // 选中状态下的文本颜色
        unselectedLabelColor: Colors.grey, // 未选中状态下的文本颜色
      ),
    );
  }
}

效果图如下:
Screenshot_2023-05-17-13-50-26-074_com.example.learning.png

备注:

  • 记得用TabController将TabBarView与TabBar结合起来,这样才能实现联动,TabBar选择时TabBarView才会刷新,TabBarView滑动切换时TabBar的焦点才会跟着变。

BottomNavigationBar实现

BottomNavigationBar介绍

BottomNavigationBar是Flutter提供的用于底部导航栏的小部件,它可以在应用程序的底部显示一组导航选项。下面是对BottomNavigationBar的详细介绍。
构造函数:

BottomNavigationBar({
  Key? key,
  required List<BottomNavigationBarItem> items, // 导航选项列表
  int currentIndex = 0, // 当前选中的索引
  Color? backgroundColor, // 背景颜色
  Color? unselectedItemColor, // 未选中项的颜色
  Color? selectedItemColor, // 选中项的颜色
  double? elevation, // 阴影高度
  BottomNavigationBarType type = BottomNavigationBarType.fixed, // 样式类型
  ValueChanged<int>? onTap, // 点击事件回调
  MouseCursor? mouseCursor, // 鼠标指针
  bool enableFeedback = true, // 是否启用触觉反馈
})

属性:

items:一个包含BottomNavigationBarItem对象的列表,表示导航栏的选项。每个BottomNavigationBarItem包含一个图标和一个可选的文本标签。
currentIndex:当前选中的选项的索引。
backgroundColor:导航栏的背景颜色。
unselectedItemColor:未选中项的颜色。
selectedItemColor:选中项的颜色。
elevation:导航栏的阴影高度。
type:导航栏的样式类型。可以是BottomNavigationBarType.fixed(固定样式,所有选项占用相等的空间)或BottomNavigationBarType.shifting(移动样式,选中的选项会突出显示)。
onTap:点击导航项时的回调函数,它接受一个int类型的参数,表示选中的选项的索引。
mouseCursor:鼠标指针的样式。
enableFeedback:是否启用触觉反馈。

BottomNavigationBar实现底部导航栏的例子

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyTabPage(),
    );
  }
}

class MyTabPage extends StatefulWidget {
  
  _MyTabPageState createState() => _MyTabPageState();
}

class _MyTabPageState extends State<MyTabPage> with SingleTickerProviderStateMixin {
  int _currentIndex = 0;
  late TabController _tabController;

  
  void initState() {
    super.initState();
    _tabController = TabController(length: 3, vsync: this); // 3是选项卡数量
    _tabController.addListener(_handleTabChange); // 添加监听器
  }

  
  void dispose() {
    _tabController.removeListener(_handleTabChange); // 移除监听器
    _tabController.dispose();
    super.dispose();
  }

  void _handleTabChange() {
    setState(() {
      _currentIndex = _tabController.index; // 更新焦点索引
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('微信'),
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          // 第一个选项卡的内容
          Container(
            child: Center(
              child: Text('聊天'),
            ),
          ),
          // 第二个选项卡的内容
          Container(
            child: Center(
              child: Text('群组'),
            ),
          ),
          // 第三个选项卡的内容
          Container(
            child: Center(
              child: Text('个人'),
            ),
          ),
        ],
      ),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (int index) {
          setState(() {
            _currentIndex = index;
            _tabController.animateTo(index); // 切换TabBarView
          });
        },
        items: [
          BottomNavigationBarItem(
            icon: Icon(Icons.chat),
            label: '聊天',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.group),
            label: '群组',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person),
            label: '个人',
          ),
        ],
      ),
    );
  }
}

效果如下:
Screenshot_2023-05-17-13-48-49-280_com.example.learning.png
我们使用了BottomNavigationBar小部件代替了TabBar。BottomNavigationBar可以放在屏幕底部,并且具有内置的标签和图标。我们将currentIndex绑定到当前选中的标签的索引,以便在用户更改标签时更新底部导航栏。我们还使用onTap回调,以便在用户点击标签时切换TabBarView中的标签页。

请注意,在此示例中,我们仍然使用了TabBarView来显示选项卡内容。我们通过将TabController传递给TabBarView来将其与BottomNavigationBar同步。这样,当用户更改底部导航栏的标签时,TabBarView也会切换到相应的标签页。我们添加了一个_handleTabChange方法来处理选项卡的变化。在initState方法中,我们将此方法添加为TabController的监听器。当TabController的索引发生变化时,_handleTabChange方法会被调用,然后我们更新底部导航栏的焦点索引_currentIndex,从而实现底部导航栏焦点随着TabBarView的滑动而更新。

在_handleTabChange方法中,我们使用了setState来触发重新构建界面,以便更新底部导航栏焦点。
这些都是必要的,不然TabBarView和BottomNavigationBar不会联动。

总结

BottomNavigationBar和TabBar实现底部导航栏哪个更好?
BottomNavigationBar和TabBar都可以用作底部导航栏,选择使用哪个取决于您的具体需求和设计偏好。以下是它们的一些特点和使用场景:

BottomNavigationBar

BottomNavigationBar是专门为底部导航栏设计的小部件,提供了内置的标签和图标,并支持固定数量的选项。
它通常用于在应用的底部提供导航功能,例如常见的底部标签栏。
BottomNavigationBar在设计上更符合平台的底部导航栏样式,可以提供更统一的用户体验。
它适合用于具有固定数量的导航选项,例如底部标签页的数量已知且固定。

TabBar

TabBar是一个通用的选项卡导航小部件,可以放置在顶部或底部,并且可以包含可滚动或固定数量的选项。
它可以用于创建自定义的导航样式,并支持更灵活的选项卡布局和交互。
TabBar适合用于具有可变数量的导航选项,例如多个选项卡页的数量可以根据用户权限或动态数据而变化。

根据实际情况选择

在实际应用中,选择使用哪个小部件更方便、更好或更常用是因人而异的。如果您的应用需要固定数量的底部导航选项,并且您希望使用内置的样式和动画,那么BottomNavigationBar可能更适合。如果您需要更多的自定义选项,例如可滚动的选项卡或与其他自定义导航组件的集成,那么TabBar可能更适合。

最佳选择取决于您的项目需求、设计风格和用户体验目标。建议根据具体情况评估这两个小部件,并选择最适合您项目的底部导航栏实现。

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

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

相关文章

代码随想录算法训练营day43 | 1049. 最后一块石头的重量 II ,494. 目标和,474.一和零,01背包问题总结

代码随想录算法训练营day43 | 1049. 最后一块石头的重量 II &#xff0c;494. 目标和&#xff0c;474.一和零 1049. 最后一块石头的重量 II解法一&#xff1a;动态规划 494. 目标和解法一&#xff1a;动态规划 474.一和零解法一&#xff1a;动态规划 01背包问题总结 1049. 最后…

商场导航地图系统,商场导航怎么实现?

商场导航怎么实现&#xff1f;在商场里面&#xff0c;手机上的导航往往接收不了信号或者不支持&#xff0c;由于室内不只是平面的&#xff0c;跟室外导航有很大的区别&#xff0c;因此&#xff0c;室内如何快速导航就成了现代化发展的趋势。电子地图作为大家最喜闻乐见的高效应…

交换机欺骗(Switch Spoofing)简介

交换机欺骗是修改设备的 MAC 地址以伪装成授权交换机端口并获得对目标网络的访问权限的过程。由于 MAC 地址对于特定设备是唯一的&#xff0c;因此大多数网络使用这些 MAC 地址来验证设备并与其通信或建立网络连接。通过欺骗授权设备或更简单地说&#xff0c;网络识别为“受信任…

redis_exporter 部署

目录 - 下载地址- 启动vim ./start.shvim ./stop.sh - 配置prometheus - 下载地址 https://github.com/oliver006/redis_exporter/releases - 启动 为了方便辨认 我更改了它的端口&#xff0c;并编了./start.sh和./stop.sh两个脚本方便以后启动&#xff0c;语句如下&#xf…

机器学习之逻辑回归、一(学习理论)

P(D|θ&#xff09; 文章目录 一、前言二、逻辑回归的由来三、到底什么是逻辑回归&#xff08;1&#xff09;. 先对逻辑回归有个大概感觉&#xff08;2&#xff09;.逻辑回归与线性回归的区别&#xff08;3&#xff09;.sigmoid函数&#xff08;4&#xff09;目标函数&#xf…

有关于ChatGPT你需要了解的内容应该都在这了,看这一篇就够啦

在国内用了很长一段时间的ChatGPT&#xff0c;每次跟小白&#xff0c;哪怕是用ChatGPT的人交流的时候&#xff0c;都感觉解释不清&#xff0c;正好今天周末&#xff0c;给大家整理一篇关于ChatGPT的科普文&#xff0c;想要了解或使用ChatGPT的人&#xff0c;一定要看完~~~ 什么…

内网渗透(CS与MSF联动) ATTCK实战系列一红队实战(一)

靶场下载地址: http://vulnstack.qiyuanxuetang.net/vuln/detail/2/ 拓扑图 环境配置 win7网络配置情况: 外网 内网域网络 Win2K3网络配置情况: 内网域网络 win2008(域控)网络配置情况: 内网域网络 渗透过程 开始之前&#xff0c;先到win7上开启phpstudy 打开网页&#…

安装 kubeadm

安装 kubeadm、kubelet 和 kubectl 基于Red Hat的发行版本 1、写入软件源 cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch enabled1 gpgcheck1 …

盘点谷歌26个插件生态;WPS AI上新与测评;Prompt中文指南;ChatGPT最新联网插件评测 | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f916; 『Google 最新发布的26个插件&#xff0c;哪些ChatGPT也有&#xff1f;』插件生态初见端倪 ▢ Google自家生态 (9个)&#xff1a;办公…

CATIA操作经典技巧问答

如何快速知道当前的CATIA作图区上的零件的放大比例? 答:选中TOOLS----->OPTIONS----->VISUALIZATION----> DISPLAY CURRENT SCALE IN PARALLEL, MODE 的选项. 在屏幕的右下方的数值表示当前作图区内的几何体的显示比例。 如何快速定义草图方向? 答:按CTRL键点选在…

Crypto VC 们最近有何动向?7 个工具助你轻松追踪

http://www.btcwbo.com/7289.html 加密 VC 和基金对初创项目的投资收益超过百万美元。它们为具有增长潜力的早期创业公司提供资金、技术支持和专业知识&#xff0c;作为交换&#xff0c;它们将获得这些公司的股份&#xff08;代币&#xff09;。 你可能经常会听到“VC 投了”之…

nacos注册中心源码分析二之服务发现

nacos服务发现 服务发现是客户端发起负载均衡(feign)调用接口的时候内部第一次调用nacos服务端接口的时候去调用的 后续调用基本上都是从客户端的缓存列表里边去取&#xff0c;拿不到才会向服务端发起调用 如果想看这一块代码可以看下ribbion源码分析ribbon源码分析 上一篇&am…

什么是互联网交换中心?为什么它很重要?

互联网交换中心&#xff08;Internet Exchange Point, IXP&#xff09;是为促进互联网骨干网的网间互联和公平竞争而设置的运营商间进行数据网际交换的机构&#xff0c;是为互联网业者提供空间进行网络互连、交换流量和资源的服务场所&#xff0c;互联网业者可以在这里利用机架…

基于自定义知识库回答问题的ChatGPT-

前言 ChatGPT是一个强大的语言模型&#xff0c;利用大规模的自然语言处理和机器学习算法&#xff0c;可以进行自然而流畅的对话&#xff0c;理解自然语言问题和回答&#xff0c;相信在座各位&#xff0c;尤其是程序员的你&#xff0c;肯定不可能还没使用过ChatGPT。 ChatGPT能…

属于开发者的交流,openGauss SIG版本规划工作会议来啦!

想参与SIG组未来半年的规划与工作&#xff1f; 想与开发者们近距离探讨需求与解决方案&#xff1f; 想将您的需求合入到openGauss的下个版本&#xff1f; 想在社区年度Summit上展现成果&#xff1f; 那就不能错过这个属于开发者的交流盛会&#xff01; 社区年度开发者大会…

取用水监测计量标准化建设,加强流量在线监测

方案背景 根据《关于强化取水口取水监测计量的意见》、《十四五”节水型社会建设规划》以及《2022年水资源管理工作要点》等政策要求&#xff0c;为强化水资源管理&#xff0c;做好水资源税改革&#xff0c;构建节水型社会&#xff0c;要全面加强取水计量监测设施建设&#xff…

计算机网络实验(ensp)-​实验2:PP协议及PAP认证

目录 实验报告&#xff1a; 实验操作 1.建立网络拓扑图并开启设备 2.修改路由器名字 1.输入命名&#xff1a;sys 从用户视图切换到系统视图 2.输入命名&#xff1a;sysname 姓名 修改路由器名字 3.重复步骤1和2配置每台路由器 3.抓包 1.点击菜单栏的“数…

计算机图形学-GAMES101-6

一、前情提要 在观察和投影变换的基础上提出了视口变换&#xff0c;最终我们会将【-1,1】^ 3 立方体转换到屏幕空间中去。 当所有图像都在屏幕空间中时&#xff0c;我们就要将所有的图像画在屏幕上&#xff0c;这个过程就是光栅化&#xff0c;光栅化就是简单的在屏幕空间的采样…

独家公布!985/211高校毕业生源数量统计Top10揭晓……

2023&#xff0c;985/211高校硕博毕业生总数约达49W。 这是在各大高校官网、官方公众号统计/整理后得到的数据。可能不完全&#xff0c;但数量已经足够庞大&#xff0c;就业竞争也更为激烈。 为了帮助大家更好地了解这些大学的毕业生源情况&#xff0c;本文将为大家揭晓&#x…

Live800:新消费浪潮涌起,在线客服系统如何“升级”?

时代在发展&#xff0c;舞台下的观众已经逐渐成长。 伴随着时代的快速发展&#xff0c;一方面&#xff0c;消费者的行为习惯和消费决策模式变迁&#xff0c;消费者的心理、兴趣及年龄层发生了巨大变化。另一方面&#xff0c;互联网信息透明化打破行业边界&#xff0c;让消费者…