文章目录
一、BottomNavigationBar 底部导航栏
二、PageView 滑动页面
三、BottomNavigationBar 与 PageView 关联
四、完整代码示例
1、核心导航组件
2、四个切换页面
3、应用启动主界面
4、运行效果
五、相关资源
一、BottomNavigationBar 底部导航栏
在 Scaffold 的 bottomNavigationBar 属性设置底部导航栏 ;
设置当前索引 : BottomNavigationBar的 currentIndex 属性设置当前底部导航栏的选中索引 , 为其设置一个变量 , 改变该变量值后 , 通过 setState 方法更新 UI 显示 ;
设置点击方法 : BottomNavigationBar 的 onTap 属性设置点击方法 , 传入 index 索引 , 该索引值是被点击的按钮索引 , 在该方法中主要操作当前的 currentIndex 属性变量 , 以及 PageView 页面跳转 ;
底部按钮设置 : BottomNavigationBar 的 item 属性设置若干 BottomNavigationBarItem 类型的点击按钮 ;
代码示例 :
bottomNavigationBar: BottomNavigationBar( /// 当前选中的导航索引 currentIndex: _currentIndex, /// 底部导航栏的点击方法 onTap: (index) { // 控制 PageView 跳转到指定的页面 _pageController.jumpToPage(index); setState(() { // 更新当前的索引值 _currentIndex = index; }); }, /// 设置底部的若干点击导航栏点击按钮 /// 注意该 List<BottomNavigationBarItem> items /// 中的按钮顺序 , 要与 PageView 中的页面顺序必须保持一致 /// 个数个顺序都要保持一致 items: datas.map((data) { return BottomNavigationBarItem( /// 默认状态下的图标, 灰色 icon: Icon( data.icon, color: Colors.grey, ), /// 选中状态下的图标, 红色 activeIcon: Icon( data.icon, color: Colors.red, ), /// 根据当前页面是否选中 , 确定 title: Text( data.title, style: TextStyle( /// 如果是选中状态 , 则设置红色 /// 如果是非选中状态, 则设置灰色 color: _currentIndex == data.index ? Colors.red : Colors.grey), ), ); }).toList(), )
二、PageView 滑动页面
PageView 作为显示的主体组件 , 设置给 Scaffold 的 body 字段 , 主要设置以下三个参数 ;
控制器 : 在 PageView 的 controller 参数设置 , PageController 类型 , 主要用于控制 PageView 的页面跳转 ;
滑动回调事件 : onPageChanged 参数设置滑动回调事件 , 传入 index 索引值 , 在该事件中 , 调用 setState 方法 , 更新底部导航栏 BottomNavigationBar 的当前索引值 , 并更新 UI 界面 ;
显示组件 : 在 children 参数中设置 Widget 数组即可 , 组件类型只要是 Widget 就行 ;
代码示例 :
/// 滑动组件 , 界面的核心元素 body: PageView( /// 控制跳转翻页的控制器 controller: _pageController, /// 页面滑动 /// 这里设置 PageView 页面滑动也能 onPageChanged: (index) { setState(() { // 更新当前的索引值 _currentIndex = index; }); }, /// Widget 组件数组 , 设置多个 Widget 组件 /// 同一时间只显示一个页面组件 children: [ HomePage(), // 首页 ImagePage(), // 图片页 SearchPage(), // 搜索页 SettingPage(), // 个人设置页 ], ),
三、BottomNavigationBar 与 PageView 关联
BottomNavigationBar 被动设备选中状态 : BottomNavigationBar 的索引通过一个在组件内部定义的私有变量 _currentIndex 控制 , 将该 _currentIndex 变量设置给底部导航栏 BottomNavigationBar 的 currentIndex 参数 , 之后可以通过调用 setState 方法修改 _currentIndex 私有变量 , 即可控制 BottomNavigationBar 的选中状态 ;
BottomNavigationBar 主动设置选中状态 : 在 BottomNavigationBar 的 onTap 参数中 , 可以获取点击的按钮索引 , 然后调用 PageView 的 PageController 的 jumpToPage 方法 实现相应的界面跳转 ;
BottomNavigationBar( /// 当前选中的导航索引 currentIndex: _currentIndex, /// 底部导航栏的点击方法 onTap: (index) { // 控制 PageView 跳转到指定的页面 _pageController.jumpToPage(index); setState(() { // 更新当前的索引值 _currentIndex = index; }); }, }
PageView 被动设置选中状态 : 在 BottomNavigationBar 底部导航栏中点击导航按钮 , 切换页面 , 使用 PageView 的 PageController 的 jumpToPage 方法进行页面跳转 ;
PageView 主动设置选中状态 : 滑动 PageView 界面 , 会回调 PageView 中的 onPageChanged 方法 , 在此处调用 setState 方法 , 在该方法中设置 _currentIndex 的值 , 进而更新 BottomNavigationBar 底部导航栏的选中状态 ;
PageView( /// 控制跳转翻页的控制器 controller: _pageController, /// 页面滑动 /// 这里设置 PageView 页面滑动也能 onPageChanged: (index) { setState(() { // 更新当前的索引值 _currentIndex = index; }); }, }
四、完整代码示例
1、核心导航组件
import 'package:flutter/material.dart';
import 'package:flutter_app/pages/home_page.dart';
import 'package:flutter_app/pages/image_page.dart';
import 'package:flutter_app/pages/search_page.dart';
import 'package:flutter_app/pages/setting_page.dart';
/// 应用的主界面组件 , 整个应用的初始根节点 class MainNavigatorWidget extends StatefulWidget { @override _MainNavigatorWidgetState createState() => _MainNavigatorWidgetState(); } /// 该类的父类 State 接受一个泛型 /// 泛型类型是 StatefulWidget 类型 TabNavigator class _MainNavigatorWidgetState extends State<MainNavigatorWidget> 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 Scaffold( /// 滑动组件 , 界面的核心元素 body: PageView( /// 控制跳转翻页的控制器 controller: _pageController, /// 页面滑动 /// 这里设置 PageView 页面滑动也能 onPageChanged: (index) { setState(() { // 更新当前的索引值 _currentIndex = index; }); }, /// Widget 组件数组 , 设置多个 Widget 组件 /// 同一时间只显示一个页面组件 children: [ HomePage(), // 首页 ImagePage(), // 图片页 SearchPage(), // 搜索页 SettingPage(), // 个人设置页 ], ), /// 设置底部导航栏按钮 bottomNavigationBar: BottomNavigationBar( /// 当前选中的导航索引 currentIndex: _currentIndex, /// 底部导航栏的点击方法 onTap: (index) { // 控制 PageView 跳转到指定的页面 _pageController.jumpToPage(index); setState(() { // 更新当前的索引值 _currentIndex = index; }); }, /// 设置底部的若干点击导航栏点击按钮 /// 注意该 List<BottomNavigationBarItem> items /// 中的按钮顺序 , 要与 PageView 中的页面顺序必须保持一致 /// 个数个顺序都要保持一致 items: datas.map((data) { return BottomNavigationBarItem( /// 默认状态下的图标, 灰色 icon: Icon( data.icon, color: Colors.grey, ), /// 选中状态下的图标, 红色 activeIcon: Icon( data.icon, color: Colors.red, ), /// 根据当前页面是否选中 , 确定 title: Text( data.title, style: TextStyle( /// 如果是选中状态 , 则设置红色 /// 如果是非选中状态, 则设置灰色 color: _currentIndex == data.index ? Colors.red : Colors.grey), ), ); }).toList(), ), ); } } /// 封装导航栏的图标与文本数据 class TabData { /// 导航数据构造函数 const TabData({this.index, this.title, this.icon}); /// 导航标题 final String title; /// 导航图标 final IconData icon; /// 索引 final int index; } /// 导航栏数据集合 const List<TabData> datas = const <TabData>[ const TabData(index: 0, title: '首页', icon: Icons.home_outlined), const TabData(index: 1, title: '图片', icon: Icons.camera), const TabData(index: 2, title: '搜索', icon: Icons.search), const TabData(index: 3, title: '设置', icon: Icons.settings), ];