1. 基本介绍
CupertinoTabScaffold、CupertinoTabView、CupertinoTabBar 是 iOS 风格的 UITabBarController 中的相关组件。CupertinoTabScaffold 可以简单的理解为这一套控件的容器,他提供了 tabBar,tabBuilder 两个属性来接收 CupertinoTabView、CupertinoTabBar。
CupertinoTabBar 很好理解了,就是 UITabBar,也就是下方选项卡。可以看这里 -> Flutter入门(51):Flutter 组件之 CupertinoTabBar 详解
CupertinoTabView 这个和 iOS 中的 View 有很大的区别,它其实并不能理解为 View。相比于一个视图,它更像是一个控制器,在 CupertinoTabView 中提供了路由,导航等功能,同时他也可以根据不同选项卡的下标提供不同的页面。
2. 示例代码
代码下载地址。如果对你有帮助的话记得给个关注,代码会根据我的 Flutter 专题不断更新。
3. 效果图
效果和 iOS 原生的 UITabBarController 一致。
4. 属性介绍
CupertinoTabScaffold 属性 | 介绍 |
---|---|
tabBar | @required 底部选项卡 |
tabBuilder | 页面构造器 |
controller | 控制器,控制默认选项卡被选中 |
backgroundColor | 背景色,没啥效果 |
resizeToAvoidBottomInset | 是否调整自身大小来避免底部嵌入,默认为 true。例如键盘弹起输入时防止输入框和键盘重叠遮挡。 |
CupertionTabBar 详解看这里 -> Flutter入门(51):Flutter 组件之 CupertinoTabBar 详解
CupertinoTabView 属性 | 介绍 |
---|---|
builder | 构造器,为不同选项卡提供不同的页面 |
navigatorKey | 导航 Key |
defaultTitle | 默认 title |
routes | 路由 |
onGenerateRoute | 拦截路由 |
onUnknownRoute | 未知路由 |
navigatorObservers | const |
关于路由之前有单独写过文章,不理解的可以看这里
Flutter入门(18):Flutter 组件之 Route 详解
Flutter入门(21):Flutter 组件之路由表封装思路详解
5. CupertinoTabScaffold 详解
5.1 示例代码
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class FMCupertinoTabScaffoldVC extends StatefulWidget{
@override
FMCupertinoTabScaffoldState createState() => FMCupertinoTabScaffoldState();
}
class FMCupertinoTabScaffoldState extends State {
@override
Widget build(BuildContext context) {
// TODO: implement build
return CupertinoTabScaffold(
tabBar: _cupertinoTabBar(), // 选项卡
// 控制器,控制选中选项卡
controller: CupertinoTabController(
initialIndex: 2,
),
backgroundColor: Colors.yellow, // 背景色,没啥效果
tabBuilder: (context, index){
return CupertinoTabView(
// 路由设置
routes: {
'/subPage/music' : (context) => FMMusicPage(),
'/subPage/chat' : (context) => FMChatPage(),
'/subPage/buy' : (context) => FMBuyPage(),
'/subPage/video' : (context) => FMVideoPage(),
},
// 构建函数,为每个选项卡提供不同页面
builder: (context){
switch (index){
case 0:
return FMMusicPage();
case 1:
return FMChatPage();
case 2:
return FMBuyPage();
case 3:
return FMVideoPage();
default :
return Container();
}
},
);
},
);
}
CupertinoTabBar _cupertinoTabBar(){
return CupertinoTabBar(
// 点击回调
onTap: (index){
print("tap Index = $index");
},
// currentIndex: 2, // 设置默认选中位置
backgroundColor: Colors.lightBlueAccent, // tabbar 背景色
activeColor: Colors.white, // 图标高亮颜色
inactiveColor: Colors.grey, // 图标未选中颜色
iconSize: 25, // 图标大小
// 边框
border: Border(
top: BorderSide(
width: 3,
color: Colors.red
),
),
items: [
_bottomNavigationBarItem(Icons.add, "第一个"),
_bottomNavigationBarItem(Icons.add, "第二个"),
_bottomNavigationBarItem(Icons.add, "第三个"),
_bottomNavigationBarItem(Icons.add, "第四个"),
],
);
}
BottomNavigationBarItem _bottomNavigationBarItem(IconData activeIcon, String title){
return BottomNavigationBarItem(
icon: Icon(Icons.ac_unit), // 图标
activeIcon: Icon(activeIcon), // 高亮图标
title: Text("$title"), // 标题
backgroundColor: Colors.yellow, // 背景色,仅在 BottomNavigatinBar 中生效,在 iOS 风格组件中无效
);
}
}
// 子选项卡页面
class FMMusicPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('音乐'),
),
child: Center(
child: Text('音乐'),
),
);
}
}
class FMChatPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('Chat'),
),
child: Center(
child: CupertinoButton(
child: Text('点我 Push 音乐页面'),
onPressed: (){
Navigator.pushNamed(context, '/subPage/music');
},
),
),
);
}
}
class FMBuyPage extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('购物'),
),
child: Center(
child: CupertinoButton(
child: Text('点我 Push 聊天页面'),
onPressed: (){
Navigator.pushNamed(context, '/subPage/chat');
},
),
),
);
}
}
class FMVideoPage extends StatelessWidget{
@override
Widget build(BuildContext context) {
// TODO: implement build
return CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('视频'),
),
child: Center(
child: CupertinoButton(
child: Text('点我 Push 购物页面'),
onPressed: (){
Navigator.pushNamed(context, '/subPage/buy');
},
),
),
);
}
}
5.2 路由详解
在 CupertinoTabView 中提供了一套新的路由,用法和常规 Route 一样。如果之前对 flutter 路由已经了解了,这里看 demo 中的示例不难理解。这里就不多赘述了,有兴趣或者不理解路由的可以看我之前写的文章。
Flutter入门(18):Flutter 组件之 Route 详解
Flutter入门(21):Flutter 组件之路由表封装思路详解
6. 技术小结
- 关于 CupertinoTabScaffold 的使用较为复杂,涉及组件较多,需要认真研究。
- CupertinoTabView 的使用不要被名字误解了,相比于一个简单的视图,它更偏向于控制器,涉及到路由,导航等多种功能。