文章目录
- 一、BottomNavigationBar 底部导航栏
- 二、PageView 滑动页面
- 三、BottomNavigationBar 与 PageView 关联
- 四、完整代码示例
- 1、核心导航组件
- 2、四个切换页面
- 3、应用启动主界面
- 4、运行效果
- 五、相关资源
一、BottomNavigationBar 底部导航栏
在 Scaffold 的 bottomNavigationBar 属性设置底部导航栏 ;
设置当前索引 : BottomNavigationBar的 currentIndex 属性设置当前底部导航栏的选中索引 , 为其设置一个变量 , 改变该变量值后 , 通过 setState 方法更新 UI 显示 ;
设置点击方法 : BottomNavigationBar 的 onTap 属性设置点击方法 , 传入 index 索引 , 该索引值是被点击的按钮索引 , 在该方法中主要操作当前的 currentIndex 属性变量 , 以及 PageView 页面跳转 ;
底部按钮设置 : BottomNavigationBar 的 item 属性设置若干 BottomNavigationBarItem 类型的点击按钮 ;
代码示例 :
代码语言:javascript复制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 就行 ;
代码示例 :
代码语言:javascript复制/// 滑动组件 , 界面的核心元素
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 方法 实现相应的界面跳转 ;
代码语言:javascript复制BottomNavigationBar(
/// 当前选中的导航索引
currentIndex: _currentIndex,
/// 底部导航栏的点击方法
onTap: (index) {
// 控制 PageView 跳转到指定的页面
_pageController.jumpToPage(index);
setState(() {
// 更新当前的索引值
_currentIndex = index;
});
},
}
PageView 被动设置选中状态 : 在 BottomNavigationBar 底部导航栏中点击导航按钮 , 切换页面 , 使用 PageView 的 PageController 的 jumpToPage 方法进行页面跳转 ;
PageView 主动设置选中状态 : 滑动 PageView 界面 , 会回调 PageView 中的 onPageChanged 方法 , 在此处调用 setState 方法 , 在该方法中设置 _currentIndex 的值 , 进而更新 BottomNavigationBar 底部导航栏的选中状态 ;
代码语言:javascript复制PageView(
/// 控制跳转翻页的控制器
controller: _pageController,
/// 页面滑动
/// 这里设置 PageView 页面滑动也能
onPageChanged: (index) {
setState(() {
// 更新当前的索引值
_currentIndex = index;
});
},
}
四、完整代码示例
1、核心导航组件
代码语言:javascript复制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),
];
2、四个切换页面
页面 1 :
代码语言:javascript复制import 'package:flutter/material.dart';
/// 应用主界面
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
/// 界面框架
return Scaffold(
/// 居中组件
body: Center(
child: Text("应用主页面"),
),
);
}
}
页面 2 :
代码语言:javascript复制import 'package:flutter/material.dart';
/// 图片页面
class ImagePage extends StatefulWidget {
@override
_ImagePageState createState() => _ImagePageState();
}
class _ImagePageState extends State<ImagePage> {
@override
Widget build(BuildContext context) {
/// 界面框架
return Scaffold(
/// 居中组件
body: Center(
child: Text("图片页面"),
),
);
}
}
页面 3 :
代码语言:javascript复制import 'package:flutter/material.dart';
/// 搜索页面
class SearchPage extends StatefulWidget {
@override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
@override
Widget build(BuildContext context) {
/// 界面框架
return Scaffold(
/// 居中组件
body: Center(
child: Text("搜索页面"),
),
);
}
}
页面 4 :
代码语言:javascript复制import 'package:flutter/material.dart';
/// 个人设置界面
class SettingPage extends StatefulWidget {
@override
_SettingPageState createState() => _SettingPageState();
}
class _SettingPageState extends State<SettingPage> {
@override
Widget build(BuildContext context) {
/// 界面框架
return Scaffold(
/// 居中组件
body: Center(
child: Text("个人设置页面"),
),
);
}
}
3、应用启动主界面
代码语言:javascript复制import 'package:flutter/material.dart';
import 'package:flutter_app/navigator/main_navigator.dart';
/// 应用主页面
void main() {
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainNavigatorWidget(),
);
}
}
4、运行效果
五、相关资源
参考资料 :
- Flutter 官网 : https://flutter.dev/
- Flutter 插件下载地址 : https://pub.dev/packages
- Flutter 开发文档 : https://flutter.cn/docs ( 强烈推荐 )
- 官方 GitHub 地址 : https://github.com/flutter
- Flutter 中文社区 : https://flutter.cn/
- Flutter 实用教程 : https://flutter.cn/docs/cookbook
- Flutter 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/15989510
- Flutter 实战电子书 : https://book.flutterchina.club/chapter1/
重要的专题 :
- Flutter 动画参考文档 : https://flutterchina.club/animations/
博客源码下载 :
- GitHub 地址 : https://github.com/han1202012/flutter_app ( 随博客进度一直更新 , 有可能没有本博客的源码 )
- 博客源码快照 : https://download.csdn.net/download/han1202012/16306822 ( 本篇博客的源码快照 , 可以找到本博客的源码 )