导航栏

底部导航栏 BottomNavigationBar

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

属性 类型 简述
items List<BottomNavigationBarItem> 底部导航栏展示的内容项
onTap ValueChanged<int> 点击导航栏子项时的回调
currentIndex int 当前选择的子项索引
type BottomNavigationBarType 底部导航栏的类型,fixedshifting两种
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时的背景颜色

任意导航栏 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 _HomePageState extends State<HomePage> 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

class _HomePageState extends State<HomePage> with SingleTickerProviderStateMixin {
  static const data = [
    Tab(text: "少林",),
    Tab(text: "武当",),
    Tab(text: "峨眉",),
    Tab(text: "崆峒",)
  ];

  PageController _pageController;
  TabController _tabController;

  @override
  void initState() {
    super.initState();
    _pageController = PageController();
    _tabController = TabController(length: data.length,vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    print("_HomePageState build ...");

    return Scaffold(
      appBar: AppBar(
        title: Text("Flutter Widget"),
        bottom: TabBar(
          onTap: (index){
            _pageController.jumpToPage(index);
          },
          controller: _tabController,
            tabs:data
        ),
      ),
      body: PageView.builder(
          itemCount: data.length,
          controller:_pageController,
          onPageChanged: (index){
            _tabController.animateTo(index);
          },
          itemBuilder: (ctx,i){
            return data[i];
      }),
    );
  }
}

保存状态

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

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

iOS 风格导航栏

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

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

CupertinoTabBar + CupertinoTabView 示例

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: [
          BottomNavigationBarItem(title: Text("首页"), icon: Icon(Icons.home)),
          BottomNavigationBarItem(title: Text("我的"), icon: Icon(Icons.account_box)),
        ],
      ),
      tabBuilder: (BuildContext context, int index) {
        return CupertinoTabView(
          builder: (context) {
            switch (index) {
              case 0:
                return FirstPage();
                break;
              case 1:
                return SecondPage();
                break;
              default:
                return FirstPage();
            }
          },
        );
      },
    );
  }
}

class FirstPage extends StatefulWidget {
  @override
  _FirstPageState createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold (
      navigationBar: CupertinoNavigationBar(
        middle: Text("首页"),
        transitionBetweenRoutes: false,
      ),
      child: Center(
        child: CupertinoButton (
          child: Text("跳转新页"),
          onPressed: () {
            Navigator.of(context,rootNavigator: true).push(
                CupertinoPageRoute(
                    builder: (BuildContext context) {
                      return NewPage();
                    }
                )
            );
          },
        ),
      ),
    );
  }
}

class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold (
      navigationBar: CupertinoNavigationBar(
        middle: Text("我的"),
      ),
      child: Center(
        child: Text("我的页面")
      ),
    );
  }
}

class NewPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        transitionBetweenRoutes: false,
      ),
      child: Container(
        alignment: Alignment.center,
        child: Text("新页面"),
      ),
    );
  }
}

公众号“编程之路从0到1”

20190301102949549

Copyright © Arcticfox 2020 all right reserved,powered by Gitbook文档修订于: 2022-05-01 12:00:54

results matching ""

    No results matching ""