文章目录
- 一、Scaffold 组件
- 二、实现顶部导航栏
- 三、DefaultTabController 导航标签控制组件
- 四、TabBar 导航按钮组件
- 五、Tab 标签组件
- 六、TabBarView 导航主体内容组件
- 七、完整代码示例
- 八、相关资源
一、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);
二、实现顶部导航栏
实现顶部导航栏需要三个组件 :
- TabBar : 该组件就是导航栏组件 , 设置多个图标按钮 ;
- TabBarView : 该组件是被导航的组件 , 设置多个布局结构 , 同时只能显示一个 ;
- DefaultTabController : 该组件用于关联控制 TabBar 和 TabBarView 组件 ;
界面组件中 , 根组件肯定是 MaterialApp , 然后下一层组件就是 DefaultTabController , 使用 DefaultTabController 包裹 Scaffold , 然后在 Scaffold 中定义的 TabBar 和 TabBarView 就会被关联再一起 ;
注意三个相等的值 :
DefaultTabController length 长度
等于
TabBar 子组件个数
等于
TabBarView 子组件个数
Google 官方给出的文档 :
[TabBar], which displays a row of tabs. ( 显示一行标签 )
[TabBarView], which displays a widget for the currently selected tab. ( 显示当前选中的标签对应的组件 )
[TabController], which coordinates tab selection between a [TabBar] and a [TabBarView]. ( 用于关联标签与选项卡 )
https://material.io/design/components/tabs.html
三、DefaultTabController 导航标签控制组件
DefaultTabController 用于关联 TabBar 和 TabBarView 组件 ;
由于 TabBar 中的组件都是无状态组件 , 或者不同的父类组件 , 导致创建 TabController 不方便时 , 就会使用该 DefaultTabController 组件 ;
DefaultTabController 组件的 length 参数必须不为空 , 并且大于 1 , length 的个数必须等于 TabBar 和 TabBarView 的个数 ;
initialIndex 初始索引值参数必须不能为空
DefaultTabController 构造函数原型 :
/// 为给定的子组件创建一个默认的导航控制器
///
/// length 参数必须不为空 , 并且大于 1 ;
/// length 的个数必须等于 TabBar 和 TabBarView 的个数 ;
///
/// initialIndex 初始索引值参数必须不能为空
const DefaultTabController({
Key? key,
required this.length,
this.initialIndex = 0,
required this.child,
}) : assert(initialIndex != null),
assert(length >= 0),
assert(length == 0 || (initialIndex >= 0 && initialIndex < length)),
super(key: key);
Google 官方给出的代码示例 :
class MyDemo extends StatelessWidget {
final List<Tab> myTabs = <Tab>[
Tab(text: 'LEFT'),
Tab(text: 'RIGHT'),
];
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: myTabs.length,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: myTabs,
),
),
body: TabBarView(
children: myTabs.map((Tab tab) {
final String label = tab.text.toLowerCase();
return Center(
child: Text(
'This is the $label tab',
style: const TextStyle(fontSize: 36),
),
);
}).toList(),
),
),
);
}
}
四、TabBar 导航按钮组件
TabBar 组件主要用于封装导航栏的图标按钮 , 主要设置一组 Tab 组件 ;
通常放在 AppBar 组件的底部 , 也就是赋值给 AppBar.bottom , 与 TabBarView 结合起来使用 ;
TabBar 中 Tab 子组件的个数 , TabController 中的 length 长度 , TabBarView 中子组件的个数 , 三者必须相等 ;
TabBar 构造函数 :
const TabBar({
Key? key,
required this.tabs,
this.controller,
this.isScrollable = false,
this.indicatorColor,
this.automaticIndicatorColorAdjustment = true,
this.indicatorWeight = 2.0,
this.indicatorPadding = EdgeInsets.zero,
this.indicator,
this.indicatorSize,
this.labelColor,
this.labelStyle,
this.labelPadding,
this.unselectedLabelColor,
this.unselectedLabelStyle,
this.dragStartBehavior = DragStartBehavior.start,
this.overlayColor,
this.mouseCursor,
this.enableFeedback,
this.onTap,
this.physics,
}) : assert(tabs != null),
assert(isScrollable != null),
assert(dragStartBehavior != null),
assert(indicator != null || (indicatorWeight != null && indicatorWeight > 0.0)),
assert(indicator != null || (indicatorPadding != null)),
super(key: key);
官方提供的 TabBar 代码示例 :
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this);
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('TabBar Widget'),
bottom: TabBar(
controller: _tabController,
tabs: <Widget>[
Tab(
icon: Icon(Icons.cloud_outlined),
),
Tab(
icon: Icon(Icons.beach_access_sharp),
),
Tab(
icon: Icon(Icons.brightness_5_sharp),
),
],
),
),
body: TabBarView(
controller: _tabController,
children: <Widget>[
Center(
child: Text('It\'s cloudy here'),
),
Center(
child: Text('It\'s rainy here'),
),
Center(
child: Text('It\'s sunny here'),
),
],
),
);
}
五、Tab 标签组件
Tab 组件是 TabBar 组件的子组件 , 每个 TabBar 组件需要设置若干个 Tab 组件 ( 至少一个 ) ;
Tab 构造函数 :
/// 创建一个材料设计风格的选项卡.
///
/// 至少设置一个 text 文本和 icon 图标 child 必须为非空 .
const Tab({
Key? key,
this.text,
this.icon,
this.iconMargin = const EdgeInsets.only(bottom: 10.0),
this.child,
}) : assert(text != null || child != null || icon != null),
assert(text == null || child == null),
super(key: key);
代码示例 :
bottom: TabBar(
/// 可左右滑动
isScrollable: true,
/// 设置顶部导航栏的图标
tabs: datas.map((TabData data) {
/// 导航栏的图标及文本
return Tab(
text: data.title,
icon: Icon(data.icon),
);
}).toList(),
),
六、TabBarView 导航主体内容组件
显示 TabBar 中当前选中的 Tab 标签对应的组件 ;
TabBarView 初始化时 , 可以只为其设置 children 参数 , 类型是 List<Widget> ;
TabBarView 构造函数 :
const TabBarView({
Key? key,
required this.children,
this.controller,
this.physics,
this.dragStartBehavior = DragStartBehavior.start,
}) : assert(children != null),
assert(dragStartBehavior != null),
super(key: key);
七、完整代码示例
import 'package:flutter/material.dart';
void main() {
runApp(
TabBarWidget()
);
}
/// 导航栏数据集合
const List<TabData> datas = const <TabData>[
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),
];
/// 顶部导航栏核心页面
class TabBarWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
/// 材料设计应用组件 , 一般作为页面的根组件
return MaterialApp(
/// 用于将 TabBar 和 TabBarView 封装起来
home: DefaultTabController(
length: datas.length,
/// 主界面框架
child: Scaffold(
/// 标题栏
appBar: AppBar(
/// 标题栏标题
title: const Text('顶部导航栏'),
/// 设置顶部导航栏
bottom: TabBar(
/// 可左右滑动
isScrollable: true,
/// 设置顶部导航栏的图标
tabs: datas.map((TabData data) {
/// 导航栏的图标及文本
return Tab(
text: data.title,
icon: Icon(data.icon),
);
}).toList(),
),
),
/// 导航栏控制的左右轮播的组件
body: TabBarView(
/// 界面显示的主体 , 通过 TabBar 切换不同的本组件显示
children: datas.map((TabData choice) {
return Padding(
padding: const EdgeInsets.all(10.0),
child: TabContent(data: choice),
);
}).toList(),
),
),
),
);
}
}
/// 通过 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: <Widget>[
/// 设置图标
Icon(data.icon, size: 128.0, color: Colors.green),
/// 设置文字
Text(data.title, style: TextStyle(color: Colors.yellow, fontSize: 50)),
],
),
),
);
}
}
/// 封装导航栏的图标与文本数据
class TabData {
/// 导航数据构造函数
const TabData({this.title, this.icon});
/// 导航标题
final String title;
// 导航图标
final IconData icon;
}
运行效果 :
八、相关资源
参考资料 :
- 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_animation ( 随博客进度一直更新 , 有可能没有本博客的源码 )
-
博客源码快照 : https://download.csdn.net/download/han1202012/16245277 ( 本篇博客的源码快照 , 可以找到本博客的源码 )