【Flutter】底部导航栏实现 ( BottomNavigationBar 底部导航栏

您所在的位置:网站首页 flutter隐藏底部导航栏 【Flutter】底部导航栏实现 ( BottomNavigationBar 底部导航栏

【Flutter】底部导航栏实现 ( BottomNavigationBar 底部导航栏

2024-06-14 15:32| 来源: 网络整理| 查看: 265

文章目录 一、Scaffold 组件二、底部导航栏整体架构三、BottomNavigationBar 底部导航栏四、BottomNavigationBarItem 导航栏条目五、PageView 组件六、完整代码示例七、相关资源

一、Scaffold 组件

Flutter 中的 Scaffold 组件实现了基础的材料设计 ( Material Design ) 可视化布局结构 ;

Scaffold 提供了显示左侧侧拉导航栏 , 底部导航 , 浮动按钮等 API ;

Scaffold 构造函数如下 :

class Scaffold extends StatefulWidget { /// Creates a visual scaffold for material design widgets. const Scaffold({ Key? key, this.appBar, // 顶部的标题栏 this.body, // 中间显示的核心部分 , 标题栏下面的部分都是 this.floatingActionButton, // 右下角的悬浮按钮 ( 可改变位置 ) this.floatingActionButtonLocation, this.floatingActionButtonAnimator, this.persistentFooterButtons, this.drawer, // 侧拉导航栏 this.onDrawerChanged, this.endDrawer, this.onEndDrawerChanged, this.bottomNavigationBar, this.bottomSheet, this.backgroundColor, this.resizeToAvoidBottomInset, this.primary = true, this.drawerDragStartBehavior = DragStartBehavior.start, this.extendBody = false, this.extendBodyBehindAppBar = false, this.drawerScrimColor, this.drawerEdgeDragWidth, this.drawerEnableOpenDragGesture = true, this.endDrawerEnableOpenDragGesture = true, this.restorationId, }) : assert(primary != null), assert(extendBody != null), assert(extendBodyBehindAppBar != null), assert(drawerDragStartBehavior != null), super(key: key); 二、底部导航栏整体架构

通过设置 Scaffold 组件的 bottomNavigationBar 字段 , 为其设置一个 BottomNavigationBar 底部导航栏组件 , 该底部导航栏的 item 设置图标与文字组件数组 , onTap 字段设置 ValueChanged 点击回调方法 , 通过该方法设置当前选择的页面索引值 ;

Scaffold 组件的主题 body 字段设置 PageView 组件 , 该组件主要设置 PageController? controller 和 List children 字段 , PageController 用于控制 PageView 中的页面跳转 , children 中就是 PageView 封装的多个界面组件 , 同一时间只显示一个 ;

三、BottomNavigationBar 底部导航栏

通过 Scaffold 组件的 bottomNavigationBar 字段 , 可以设置底部导航栏菜单 , 设置一个 BottomNavigationBar 组件 ;

BottomNavigationBar 组件中可设置 int currentIndex 当前的索引 , ValueChanged? onTap 点击事件 ,

BottomNavigationBar 组件需要设置组件的类型 , 在 BottomNavigationBarType? type 字段设置 , 有两个可选类型 , fixed 和 shifting ;

enum BottomNavigationBarType { /// BottomNavigationBar 导航栏底部的 BottomNavigationBarItem 宽度不变 fixed, /// BottomNavigationBar 导航栏底部的 BottomNavigationBarItem 组件的位置和大小 , /// 都会根据当前点击的选项而改变 , /// 改变的时候有切换动画 /// 选中的状态下显示底部图标的文本 /// 不选中的状态下隐藏底部的文本内容 shifting, }

BottomNavigationBar 的 List items 字段接受 BottomNavigationBarItem 组件集合 ;

底部导航栏点击事件 , ValueChanged? onTap 字段设置点击事件 , 传入的参数是点击的底部导航栏索引值 ;

BottomNavigationBar 构造函数 :

BottomNavigationBar({ Key? key, required this.items, this.onTap, this.currentIndex = 0, this.elevation, this.type, Color? fixedColor, this.backgroundColor, this.iconSize = 24.0, Color? selectedItemColor, this.unselectedItemColor, this.selectedIconTheme, this.unselectedIconTheme, this.selectedFontSize = 14.0, this.unselectedFontSize = 12.0, this.selectedLabelStyle, this.unselectedLabelStyle, this.showSelectedLabels, this.showUnselectedLabels, this.mouseCursor, this.enableFeedback, }) : assert(items != null), assert(items.length >= 2), assert( items.every((BottomNavigationBarItem item) => item.title != null) || items.every((BottomNavigationBarItem item) => item.label != null), 'Every item must have a non-null title or label', ), assert(0 = 0.0), assert( selectedItemColor == null || fixedColor == null, 'Either selectedItemColor or fixedColor can be specified, but not both' ), assert(selectedFontSize != null && selectedFontSize >= 0.0), assert(unselectedFontSize != null && unselectedFontSize >= 0.0), selectedItemColor = selectedItemColor ?? fixedColor, super(key: key);

代码示例 :

BottomNavigationBar( /// 设置当前的导航页面索引 currentIndex: _currentIndex, /// 导航栏按钮点击事件 onTap: (pageIndex) { /// 跳转到对应的导航页面 _pageController.jumpToPage(pageIndex); setState(() { _currentIndex = pageIndex; }); }, /// 图标和文本位置不变 type: BottomNavigationBarType.fixed, /// 底部导航栏的按钮条目 items: datas.map((TabData data) { /// 单个按钮条目 return BottomNavigationBarItem( // 普通状态下的图标 , 绿色 icon: Icon( data.icon, color: Colors.green, ), /// 选中状态下的图标 , 红色 activeIcon: Icon( data.icon, color: Colors.red, ), /// 与 text 类似 , 只能设置一个 label: data.title, ); }).toList(), ), 四、BottomNavigationBarItem 导航栏条目

BottomNavigationBar 中需要设置 BottomNavigationBarItem 数组元素 , 这就需要创建若干 BottomNavigationBarItem 组件 ;

BottomNavigationBarItem 中可以设置

默认图标 Widget icon底部文案 Widget? title选中状态图标 Widget activeIcon背景颜色 Color? backgroundColor

BottomNavigationBarItem 组件构造函数 :

const BottomNavigationBarItem({ required this.icon, @Deprecated( 'Use "label" instead, as it allows for an improved text-scaling experience. ' 'This feature was deprecated after v1.19.0.' ) this.title, this.label, Widget? activeIcon, this.backgroundColor, this.tooltip, }) : activeIcon = activeIcon ?? icon, assert(label == null || title == null), assert(icon != null); 五、PageView 组件

PageView 组件最重要的两个字段 :

PageController? controllerList children

PageController 用于控制 PageView 的跳转 , PageController 主要作用是调用 void jumpToPage(int page) 方法 , 进行页面跳转 ;

jumpToPage 页面跳转在底部菜单栏的 onTap 点击事件中调用 , 更新当前页面后 , 需要调用 setState 方法更新界面 ;

PageView 构造函数 :

PageView({ Key? key, this.scrollDirection = Axis.horizontal, // 设置滚动方向 垂直 / 水平 this.reverse = false, // 反向滚动 PageController? controller, // 滚动控制类 this.physics, // 滚动逻辑 , 不滚动 / 滚动 / 滚动到边缘是否反弹 this.pageSnapping = true, // 如果设置 false , 则无法进行页面手势捕捉 this.onPageChanged, // 页面切换时回调该函数 List children = const [], this.dragStartBehavior = DragStartBehavior.start, this.allowImplicitScrolling = false, this.restorationId, this.clipBehavior = Clip.hardEdge, }) : assert(allowImplicitScrolling != null), assert(clipBehavior != null), controller = controller ?? _defaultPageController, childrenDelegate = SliverChildListDelegate(children), super(key: key);

PageView 代码示例 :

/// 滑动组件 , 界面的核心元素 PageView( /// 控制跳转翻页的控制器 controller: _pageController, /// Widget 组件数组 , 设置多个 Widget 组件 children: datas.map((TabData data) { return Padding( /// 内边距 20 padding: const EdgeInsets.all(20.0), /// PageView 中单个显示的组件 child: TabContent(data: data), ); }).toList(), physics: NeverScrollableScrollPhysics(), ), 六、完整代码示例

完整代码示例 :

import 'package:flutter/material.dart'; /// 底部导航栏示例 void main() { runApp( BottomNavigatorWidget() ); } class BottomNavigatorWidget extends StatefulWidget { @override _BottomNavigatorWidgetState createState() => _BottomNavigatorWidgetState(); } class _BottomNavigatorWidgetState extends State with SingleTickerProviderStateMixin { /// 当前的索引值 int _currentIndex = 0; /// PageView 控制器 , 用于控制 PageView var _pageController = PageController( /// 初始索引值 initialPage: 0, ); @override void dispose() { super.dispose(); /// 销毁 PageView 控制器 _pageController.dispose(); } @override Widget build(BuildContext context) { /// 根组件 return MaterialApp( home: Scaffold( /// 滑动组件 , 界面的核心元素 body: PageView( /// 控制跳转翻页的控制器 controller: _pageController, /// Widget 组件数组 , 设置多个 Widget 组件 children: datas.map((TabData data) { return Padding( /// 内边距 20 padding: const EdgeInsets.all(20.0), /// PageView 中单个显示的组件 child: TabContent(data: data), ); }).toList(), physics: NeverScrollableScrollPhysics(), ), bottomNavigationBar: BottomNavigationBar( /// 设置当前的导航页面索引 currentIndex: _currentIndex, /// 导航栏按钮点击事件 onTap: (pageIndex) { /// 跳转到对应的导航页面 _pageController.jumpToPage(pageIndex); setState(() { _currentIndex = pageIndex; }); }, /// 图标和文本位置不变 type: BottomNavigationBarType.fixed, /// 底部导航栏的按钮条目 items: datas.map((TabData data) { /// 单个按钮条目 return BottomNavigationBarItem( // 普通状态下的图标 , 绿色 icon: Icon( data.icon, color: Colors.green, ), /// 选中状态下的图标 , 红色 activeIcon: Icon( data.icon, color: Colors.red, ), /// 与 text 类似 , 只能设置一个 label: data.title, ); }).toList(), ), ), ); } } /// 封装导航栏的图标与文本数据 class TabData { /// 导航数据构造函数 const TabData({this.title, this.icon}); /// 导航标题 final String title; // 导航图标 final IconData icon; } /// 导航栏数据集合 const List datas = const [ const TabData(title: '3D', icon: Icons.threed_rotation), const TabData(title: '打印机', icon: Icons.print), const TabData(title: '动画', icon: Icons.animation), const TabData(title: '变换', icon: Icons.transform), const TabData(title: '高度', icon: Icons.height), const TabData(title: '描述', icon: Icons.description), const TabData(title: '向前', icon: Icons.forward), const TabData(title: '相机', icon: Icons.camera), const TabData(title: '设置', icon: Icons.settings), const TabData(title: '学位', icon: Icons.school), ]; /// 通过 TabBar 导航栏切换展示的主要内容 /// 用于在 TabBarView 中显示的组件 class TabContent extends StatelessWidget { const TabContent({Key key, this.data}) : super(key: key); /// 根据该数据条目生成组件 final TabData data; @override Widget build(BuildContext context) { TextStyle textStyle = TextStyle(color: Colors.yellow, fontSize: 50); return Card( /// 设置 20 像素边距 margin: EdgeInsets.all(20), /// 设置阴影 elevation: 10, /// 卡片颜色黑色 color: Colors.black, /// 卡片中的元素居中显示 child: Center( /// 垂直方向的线性布局 child: Column( /// 在主轴 ( 垂直方向 ) 占据的大小 mainAxisSize: MainAxisSize.min, /// 居中显示 crossAxisAlignment: CrossAxisAlignment.center, children: [ /// 设置图标 Icon(data.icon, size: 128.0, color: Colors.green), /// 设置文字 Text(data.title, style: TextStyle(color: Colors.yellow, fontSize: 50)), ], ), ), ); } }

运行效果 :

在这里插入图片描述

七、相关资源

参考资料 :

Flutter 官网 : https://flutter.dev/Flutter 插件下载地址 : https://pub.dev/packagesFlutter 开发文档 : https://flutter.cn/docs ( 强烈推荐 )官方 GitHub 地址 : https://github.com/flutterFlutter 中文社区 : https://flutter.cn/Flutter 实用教程 : https://flutter.cn/docs/cookbookFlutter CodeLab : https://codelabs.flutter-io.cn/Dart 中文文档 : https://dart.cn/Dart 开发者官网 : https://api.dart.dev/Flutter 中文网 : https://flutterchina.club/ , http://flutter.axuer.com/docs/Flutter 相关问题 : https://flutterchina.club/faq/ ( 入门阶段推荐看一遍 )GitHub 上的 Flutter 开源示例 : https://download.csdn.net/download/han1202012/15989510Flutter 实战电子书 : https://book.flutterchina.club/chapter1/

重要的专题 :

Flutter 动画参考文档 : https://flutterchina.club/animations/

博客源码下载 :

GitHub 地址 : https://github.com/han1202012/flutter_frame ( 随博客进度一直更新 , 有可能没有本博客的源码 )

博客源码快照 : https://download.csdn.net/download/han1202012/16276633 ( 本篇博客的源码快照 , 可以找到本博客的源码 )



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3