Flutter入门(53):Flutter 组件之 CupertinoTabScaffold、CupertinoTabView 详解

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 一致。

CupertinoTabScaffold.gif

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 [] 为 CupertinoTabView 创建的导航提供观察者 List

关于路由之前有单独写过文章,不理解的可以看这里
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');
          },
        ),
      ),
    );
  }
}
CupertinoTabScaffold.gif

5.2 路由详解

在 CupertinoTabView 中提供了一套新的路由,用法和常规 Route 一样。如果之前对 flutter 路由已经了解了,这里看 demo 中的示例不难理解。这里就不多赘述了,有兴趣或者不理解路由的可以看我之前写的文章。

Flutter入门(18):Flutter 组件之 Route 详解
Flutter入门(21):Flutter 组件之路由表封装思路详解

6. 技术小结

  • 关于 CupertinoTabScaffold 的使用较为复杂,涉及组件较多,需要认真研究。
  • CupertinoTabView 的使用不要被名字误解了,相比于一个简单的视图,它更偏向于控制器,涉及到路由,导航等多种功能。

你可能感兴趣的:(Flutter入门(53):Flutter 组件之 CupertinoTabScaffold、CupertinoTabView 详解)