Flutter——WidgetBottomNavigationBar与CupertinoTabScaffold

Posted Jason Zhang~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter——WidgetBottomNavigationBar与CupertinoTabScaffold相关的知识,希望对你有一定的参考价值。

底部导航栏 BottomNavigationBar

App应用中底部导航栏是超级常见的。android中实现底部导航栏的方式有很多种,Flutter中也存在多种方式,这里介绍使用起来简单的官方系统控件BottomNavigationBar方式,该方式只能点击切换不同界面,不支持滑动切换。
本文实现效果如图:

常用属性

  • items
    tab集合,item类是BottomNavigationBarItem。
    BottomNavigationBarItem的常用属性:
    • icon
      图标控件。Material Design中不能为空。
    • title
      标题字符串。Material Design中不能为空。
    • activeIcon
      激活状态下的图标控件,一般情况下不会设置该属性。
  • currentIndex
    items的激活状态的下标。
  • onTap
    items子项的点击事件,一般情况下我们调用setState方法更新currentIndex的值来刷新底部导航栏的UI。
  • elevation
    Z轴偏移值,默认值为8,底部与上面会有明显的立体隔层效果。如果改成0则是平面顺滑的效果。
  • fixedColor、selectedItemColor
    选中item的文字和图标的颜色值,默认为主题颜色。两者不能同时设置。
  • unselectedItemColor
    未选中的item的色值,默认淡黑色。
  • backgroundColor
    导航栏背景色值。
  • iconSize
    图标大小,默认24,一般不建议修改。
  • selectedFontSize、unselectedFontSize
    选中item的文字大小、未选中item的文字大小,默认分别为14、12。

简单代码:

import 'package:flutter/material.dart';
import 'package:flutter_demo/pages/PageOne.dart';
import 'package:flutter_demo/pages/PageThree.dart';
import 'package:flutter_demo/pages/PageTwo.dart';

/// create on 2019/5/21 by JasonZhang
/// desc:主界面
class MainHome extends StatelessWidget 
  @override
  Widget build(BuildContext context) => new MaterialApp(home: MyHomePage());


class MyHomePage extends StatefulWidget 
  @override
  State<StatefulWidget> createState() => new MyHomePageState();


class MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin 
  List<Widget> mPages = List<Widget>(); // 主界面的页面列表
  int mCurrentIndex = 0; // 当前展示的界面下标

  @override
  void initState() 
    super.initState();
    mPages
      ..add(PageOne())
      ..add(PageTwo())
      ..add(PageThree()); // 初始化申明三个Tab页面。 .. 串起来
//    mPages.add(PageOne());
//    mPages.add(PageTwo());
//    mPages.add(PageThree());
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: "首页主界面",
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Scaffold(
        body: mPages[mCurrentIndex], // body显示的界面
        bottomNavigationBar: new BottomNavigationBar(
          items: [
            // 底部三个item,指定图标和文案。Icons.home等图标是系统自带提供的。
            // currentIndex的item的图标和文案颜色为theme颜色,未激活状态的为默认黑色
            // 也可以用activeIcon指定激活状态下的ICON图标,一般不会这样做
            BottomNavigationBarItem(
                icon: Icon(Icons.home),
                title: Text('模板中心'),
                /*activeIcon: Icon(Icons.access_alarm)*/),
            BottomNavigationBarItem(
                icon: Icon(Icons.list), title: Text('我的作品')),
            BottomNavigationBarItem(
                icon: Icon(Icons.message), title: Text('我的信息'))
          ],
          currentIndex: mCurrentIndex, // 指定下标值等于mCurrentIndex变量
          onTap: (int index) 
            // 点击事件,点击下标值赋给mCurrentIndex,触发改变currentIndex值、刷新底部导航栏的样式
            setState(() 
              mCurrentIndex = index;
            );
          ,
        ),
      ),
    );
  



import 'package:flutter/material.dart';

class PageOne extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      title: "模板中心",
      theme: ThemeData(primarySwatch: Colors.blue),
      home: Scaffold(
        appBar: AppBar(title: Text("模板中心")),
      ),
    );
  

PageTwo、PageThree代码与PageOne几乎一样。

本文源码:TAG,下载源码需指定tag。

20190530更新

实际使用中发现,BottomNavigationBar的方式在切换Tab时,界面每次展示都是重新创建的,如果有网络请求等每次都会进行请求。网上有提供一些方法解决这个问题,个人觉得有点复杂就没尝试,而是换了一个实现方式:CupertinoTabScaffold。使用方式类似,语法等也简单就不详细介绍了,实现效果与BottomNavigationBar的操作一致,也只能点击切换。
更改后源码:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_demo/pages/PageOne.dart';
import 'package:flutter_demo/pages/PageThree.dart';
import 'package:flutter_demo/pages/PageTwo.dart';

/// create on 2019/5/21 by JasonZhang
/// desc:主界面
class MainHome extends StatelessWidget 
  @override
  Widget build(BuildContext context) => new MaterialApp(home: MyHomePage());


class MyHomePage extends StatefulWidget 
  @override
  State<StatefulWidget> createState() => new MyHomePageState();


class MyHomePageState extends State<MyHomePage> 
  List<Widget> mPageList = new List();

  @override
  void initState() 
    super.initState();
    mPageList.add(new PageOne());
    mPageList.add(new PageTwo());
    mPageList.add(new PageThree());
  

  @override
  Widget build(BuildContext context) 
    return MaterialApp(
        title: "首页主界面",
        theme: ThemeData(primarySwatch: Colors.blue),
        home: CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              backgroundColor: Colors.white,
              items: [
                // 底部三个item,指定图标和文案。Icons.home等图标是系统自带提供的。
                BottomNavigationBarItem(
                  icon: Icon(
                    Icons.home,
                    size: 24,
                  ),
                  title: Text('模板中心'),
                ),
                BottomNavigationBarItem(
                    icon: Icon(
                      Icons.list,
                      size: 24,
                    ),
                    title: Text('我的作品')),
                BottomNavigationBarItem(
                    icon: Icon(
                      Icons.message,
                      size: 24,
                    ),
                    title: Text('我的信息'))
              ],
            ),
            tabBuilder: (BuildContext context, int index) 
              // 需要放在集合中指向每次复用对象,如果这里写new PageOne()则每次也是重新创建。
              return mPageList[index];
            ));
  


本次更新源码:TAG,下载源码需指定tag。

以上是关于Flutter——WidgetBottomNavigationBar与CupertinoTabScaffold的主要内容,如果未能解决你的问题,请参考以下文章

[Flutter] flutter项目一直卡在 Running Gradle task 'assembleDebug'...

flutter 日志输出,Flutter打印日志,flutter log,flutter 真机日志

Flutter开发 Flutter 包和插件 ( Flutter 包和插件简介 | 创建 Flutter 插件 | 创建 Dart 包 )

flutter与原生混编(iOS)

Flutter-布局

如何解决flutter gradle build error?C:\flutter\packages\flutter_tools\gradle\flutter.gradle' line: 991