美文网首页
Flutter开发2:导航栏

Flutter开发2:导航栏

作者: 十二栗子 | 来源:发表于2022-05-04 19:35 被阅读0次

    底部导航栏 BottomNavigationBar

    它是属于 Scaffold 中的一个位于底部的控件,与 BottomNavigationBarItem 配合使用

    属性名 类型 简介
    items List<BottomNavigationBarItem> 底部导航栏展示的内容项
    onTap ValueChanged<int> 点击导航栏子项时的回调
    currentIndex int 当前选择的子项索引
    type BottomNavigationBarType 底部导航栏的类型,fixed、shifting两种
    selectedItemColor Color 选中时子项的颜色
    unselectedItemColor Color 未选中时子项的颜色
    selectedLabelStyle TextStyle 选中时子项文字的style
    unselectedLabelStyle TextStyle 未选中时子项文字的style
    fixedColor Color type为fixed时导航栏的颜色,默认使用ThemeData.primaryColor
    iconSize double 图标大小

    需要注意,BottomNavigationBar如果不指定type,则当items小于4个时,type属性值为fixed,大于或等于4个时,则值会变为shifting,通常需要显式的将type设置为fixed以达到期望的效果

    BottomNavigationBarItem 属性

    属性名 类型 简介
    icon Widget 要显示的图标
    title Widget 要显示的文字
    activeIcon Widget 选中时展示的icon
    backgroundColor Color type为shifting时的背景颜色
     int _currentBottomBarIndex = 0;
    
     BottomNavigationBar(
            items: const [
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: '首页',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.park),
                label: '广场',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.shopping_cart),
                label: '购物车',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.person),
                label: '我的',
              )
            ],
            type: BottomNavigationBarType.fixed,
            selectedItemColor: Colors.purple,
            unselectedItemColor: Colors.grey,
            selectedFontSize: 16,
            unselectedFontSize: 14,
            currentIndex: _currentBottomBarIndex,
            selectedLabelStyle: const TextStyle(color: Colors.purple),
            unselectedLabelStyle: const TextStyle(color: Colors.grey),
            onTap: (index){
              setState(() {
                _currentBottomBarIndex = index;
              });
            },
          ),
    
    WX20220424-113110.png

    任意导航栏 TabBar

    它是切换Tab页的入口,通常会放到AppBar控件中的bottom属性中使用,也可放到其他布局位置,其子元素按水平横向排列布局,一般会与TabBarView组合使用,形成联动效果。

    属性名 类型 简介
    tabs List<Widget> 要显示的Tab列表,通常使用Tab控件
    controller TabController 要显示的文字
    isScrollable bool 是否可滚动
    indicatorColor Color 指示器颜色
    indicatorWeight double 指示器厚度
    indicatorPadding EdgeInsetsGeometry 底部指示器的Padding
    indicator Decoration 指示器decoration,例如边框等
    indicatorSize TabBarIndicatorSize 指示器大小计算方式
    labelColor Color 选中Tab文字颜色
    labelStyle TextStyle 选中Tab文字Style
    unselectedLabelColor Color 未选中Tab中文字颜色
    unselectedLabelStyle TextStyle 未选中Tab中文字style

    TabBar + TabBarView

    TabBarView是Tab页的内容容器,其内放置Tab页的主体内容。

    class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
    
      @override
      void initState() {
        super.initState();
        controller = TabController(length: 4,vsync: this);
      }
    
      TabController controller;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Flutter Widget"),
            bottom: TabBar(
              controller: controller,
                tabs:[
                  Tab(text: "社会心理学",),
                  Tab(text: "发展心理学",),
                  Tab(text: "变态心理学",),
                  Tab(text: "健康心理学",)
                ]
            ),
          ),
          body: TabBarView(
            controller: controller,
            children: <Widget>[
              Icon(Icons.access_time),
              Icon(Icons.accessibility_new),
              Icon(Icons.keyboard),
              Icon(Icons.airline_seat_flat),
            ],
          ),
        );
      }
    }
    

    当我们不需要通过代码去手动切换Tab页时,可使用默认的控制器DefaultTabController

    TabBar + PageView

    
    

    保存状态

    直接使用如上方案,在每次切换Page 页时,页面都会重新创建,initState重新执行,想要提升性能,达到我们期望的效果,则需要使用如下步骤保存状态

    在State类上混入AutomaticKeepAliveClientMixin类
    重写wantKeepAlive方法,并返回true
    在页面的build方法中,调用super.build

    iOS 风格导航栏

    关于部分iOS风格的控件,可以查看 Cupertino 官方文档

    Flutter 官方正在逐渐完善Cupertino风格的控件体系,但总的来说仍然存在一些问题,目前还不太建议使用,这里仅作为介绍。

    CupertinoTabBar + CupertinoTabView 示例

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: '页面框架',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(),
        );
      }
    }
    
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({Key? key}) : super(key: key);
    
      @override
      _MyHomePageState createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      @override
      Widget build(BuildContext context) {
        return CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: const [
              BottomNavigationBarItem(label: "首页", icon: Icon(Icons.home)),
              BottomNavigationBarItem(label: "我的", icon: Icon(Icons.account_box)),
            ],
          ),
          tabBuilder: (BuildContext context, int index) {
            return CupertinoTabView(
              builder: (context) {
                switch (index) {
                  case 0:
                    return const FirstPage();
                    break;
                  case 1:
                    return const SecondPage();
                    break;
                  default:
                    return const FirstPage();
                }
              },
            );
          },
        );
      }
    }
    
    class FirstPage extends StatefulWidget {
      const FirstPage({Key? key}) : super(key: key);
    
      @override
      _FirstPageState createState() => _FirstPageState();
    }
    
    class _FirstPageState extends State<FirstPage> {
      @override
      Widget build(BuildContext context) {
        return CupertinoPageScaffold (
          navigationBar: const CupertinoNavigationBar(
            middle: Text("首页"),
            transitionBetweenRoutes: false,
          ),
          child: Center(
            child: CupertinoButton (
              child: const Text("跳转新页"),
              onPressed: () {
                Navigator.of(context,rootNavigator: true).push(
                    CupertinoPageRoute(
                        builder: (BuildContext context) {
                          return const NewPage();
                        }
                    )
                );
              },
            ),
          ),
        );
      }
    }
    
    class SecondPage extends StatefulWidget {
      const SecondPage({Key? key}) : super(key: key);
    
      @override
      _SecondPageState createState() => _SecondPageState();
    }
    
    class _SecondPageState extends State<SecondPage> {
      @override
      Widget build(BuildContext context) {
        return const CupertinoPageScaffold (
          navigationBar: CupertinoNavigationBar(
            middle: Text("我的"),
          ),
          child: Center(
              child: Text("我的页面")
          ),
        );
      }
    }
    
    class NewPage extends StatelessWidget {
      const NewPage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return CupertinoPageScaffold(
          navigationBar: const CupertinoNavigationBar(
            transitionBetweenRoutes: false,
          ),
          child: Container(
            alignment: Alignment.center,
            child: const Text("新页面"),
          ),
        );
      }
    }
    
    

    相关文章

      网友评论

          本文标题:Flutter开发2:导航栏

          本文链接:https://www.haomeiwen.com/subject/bkktyrtx.html