[Flutter]flutter基礎(chǔ)之組件基礎(chǔ)(六)

一、概述

上篇文章介紹 MaterialApp 、Scaffold ,但是沒(méi)有內(nèi)容比較多,沒(méi)有介紹完畢。本篇文章繼續(xù)上文繼續(xù)說(shuō)明。

二、 Scaffold Widget 補(bǔ)充

bottomNavigationBarScaffold 的屬性,用來(lái)設(shè)置應(yīng)用程序的底部應(yīng)用或?qū)Ш綑?,其是一個(gè) Widget ,通常使用 BottomAppBarBottomNavigationBar 。主要用來(lái)顯示消息以及提供特定功能的導(dǎo)航。

BottomAppBar 是一個(gè)頂部可以有凹口的 Widget ,是一個(gè) StatefulWidget 。通常與 FloatingActionButton 一起使用。其構(gòu)造方法如下:

const BottomAppBar({
  Key key,
  //Color類(lèi)型可選命名參數(shù),底部程序欄的背景色
  this.color,
  //double類(lèi)型可選命名參數(shù),相對(duì)于其父應(yīng)用程序欄放置底部應(yīng)用程序欄的z坐標(biāo)
  this.elevation,
  //NotchedShape類(lèi)型可選命名參數(shù),為浮動(dòng)操作按鈕制作的凹槽
  this.shape,
  //Clip類(lèi)型可選命名參數(shù),設(shè)置內(nèi)容裁剪方式
  this.clipBehavior = Clip.none,
  //double類(lèi)型可選命名參數(shù),浮動(dòng)動(dòng)作按鈕和底部應(yīng)用欄的凹口之間的邊距
  this.notchMargin = 4.0,
  //Widget類(lèi)型可選命名參數(shù),要顯示的Widget
  this.child,
})

使用如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyFirstPage(),
    );;
  }
}

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page 1"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Center(child: Text("主體內(nèi)容"),),
      ),
      endDrawer: Drawer(),
      bottomNavigationBar: BottomAppBar(
        color: Colors.deepPurpleAccent,
        child: Text("底部BottomAppBar"),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          print("點(diǎn)擊");
        },
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}

如果不提供 BottomAppBarchild 設(shè)置,不會(huì)拋出異常,但是不會(huì)顯示 BottomAppBar

本例的效果如下:

2020312245.jpg

如果想要設(shè)置 BottomAppBar 的高度,可以通過(guò)嵌套使用帶有高度的 Widget ,如下使用 Container

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page 1"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Center(child: Text("主體內(nèi)容"),),
      ),
      endDrawer: Drawer(),
      bottomNavigationBar: BottomAppBar(
        color: Colors.deepPurpleAccent,
        child: Container(
          child: Text("底部BottomAppBar"),
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          print("點(diǎn)擊");
        },
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
    );
  }
}
2020312513.jpg

使用有凹口的 BottomAppBar 需要 shapeFloatingActionButtonLocation.centerDockedFloatingActionButtonLocation.endDocked 配合使用。如下:

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page 1"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Center(child: Text("主體內(nèi)容"),),
      ),
      endDrawer: Drawer(),
      bottomNavigationBar: BottomAppBar(
        color: Colors.deepPurpleAccent,
        shape: const CircularNotchedRectangle(),
        child: Container(
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          print("點(diǎn)擊");
        },
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

效果如下圖:

2020312725.jpg

BottomAppBar 中也可以顯示多個(gè) Widget ,需要使用 Row 橫向布局 Widget 容器,后面會(huì)詳細(xì)介紹 Row 。使用如下:

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page 1"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Center(child: Text("主體內(nèi)容"),),
      ),
      endDrawer: Drawer(),
      bottomNavigationBar: BottomAppBar(
        color: Colors.deepPurpleAccent,
        shape: const CircularNotchedRectangle(),
        child: Container(
          child: Row(
            children: <Widget>[
              IconButton(icon: Icon(Icons.print), onPressed: (){}),
              IconButton(icon: Icon(Icons.add), onPressed: (){}),
              IconButton(icon: Icon(Icons.add_a_photo), onPressed: (){}),
            ],
          ),
          height: 50.0,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: (){
          print("點(diǎn)擊");
        },
        child: Icon(Icons.add),
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
    );
  }
}

效果如下圖:

2020312739.jpg

BottomNavigationBar 主要用于應(yīng)用的底部導(dǎo)航,繼承自 StatefulWidget ,為有狀態(tài)的 Widget ,構(gòu)造函數(shù)如下:

BottomNavigationBar({
  Key key,
  //List<BottomNavigationBarItem>類(lèi)型必傳參數(shù),底部導(dǎo)航欄中的選項(xiàng)
  @required this.items,
  //ValueChanged<int>類(lèi)型可選命名參數(shù),點(diǎn)擊某個(gè)選項(xiàng)時(shí)的回調(diào)函數(shù)
  this.onTap,
  //int類(lèi)型可選命名參數(shù),當(dāng)前被選擇的選項(xiàng)索引
  this.currentIndex = 0,
  //double類(lèi)型可選命名參數(shù),此底部導(dǎo)航欄的z坐標(biāo)。
  this.elevation = 8.0,
  //BottomNavigationBarType類(lèi)型可選命名參數(shù),定義底部導(dǎo)航欄的布局和行為
  BottomNavigationBarType type,
  //Color類(lèi)型可選命名參數(shù),被選擇的選項(xiàng)的顏色,get屬性
  Color fixedColor,
  //Color類(lèi)型可選命名參數(shù),底部導(dǎo)航欄背景色
  this.backgroundColor,
  //double類(lèi)型可選命名參數(shù),底部導(dǎo)航中的圖標(biāo)的大小
  this.iconSize = 24.0,
  //Color類(lèi)型可選命名參數(shù),所選底部導(dǎo)航圖標(biāo)和底部導(dǎo)航圖標(biāo)標(biāo)簽的顏色
  Color selectedItemColor,
  //Color類(lèi)型可選命名參數(shù),未選擇的底部導(dǎo)航圖標(biāo)和底部導(dǎo)航圖標(biāo)標(biāo)簽的顏色
  this.unselectedItemColor,
  //IconThemeData類(lèi)型可選命名參數(shù),當(dāng)前選定的底部導(dǎo)航圖標(biāo)中圖標(biāo)的大小、不透明度和顏色
  this.selectedIconTheme = const IconThemeData(),
  //IconThemeData類(lèi)型可選命名參數(shù),當(dāng)前未選中的底部導(dǎo)航圖標(biāo)中圖標(biāo)的大小、不透明度和顏色
  this.unselectedIconTheme = const IconThemeData(),
  //double類(lèi)型可選命名參數(shù),選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的字體大小
  this.selectedFontSize = 14.0,
  //double類(lèi)型可選命名參數(shù),未選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的字體大小
  this.unselectedFontSize = 12.0,
  //TextStyle類(lèi)型可選命名參數(shù),選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的文本樣式。
  this.selectedLabelStyle,
  //TextStyle類(lèi)型可選命名參數(shù),未選擇時(shí)底部導(dǎo)航項(xiàng)標(biāo)簽的文本樣式。
  this.unselectedLabelStyle,
  //bool類(lèi)型可選命名參數(shù),是否為選擇的底部導(dǎo)航圖標(biāo)顯示標(biāo)簽文本
  this.showSelectedLabels = true,
  //bool類(lèi)型可選命名參數(shù),是否為未選定的底部導(dǎo)航項(xiàng)顯示標(biāo)簽文本
  bool showUnselectedLabels,
})

BottomNavigationBarItem 為帶有圖標(biāo)和標(biāo)題的交互式按鈕,通常與 BottomNavigationBar 一起使用,構(gòu)造方法如下:

const BottomNavigationBarItem({
  //Widget類(lèi)型必傳參數(shù),底部導(dǎo)航選項(xiàng)的圖標(biāo)
  @required this.icon,
  //Widget類(lèi)型可選命名參數(shù),底部導(dǎo)航選項(xiàng)的標(biāo)題
  this.title,
  //Widget類(lèi)型可選命名參數(shù),選擇底部導(dǎo)航選項(xiàng)的替代圖標(biāo)。當(dāng)選項(xiàng)被選擇時(shí)將使用此設(shè)置的圖標(biāo),如果不為null
  Widget activeIcon,
  //Color類(lèi)型可選命名參數(shù),底部導(dǎo)航欄的背景徑向動(dòng)畫(huà)的顏色。只有當(dāng)設(shè)置BottomNavigationBarType.shifting
  //時(shí)才生效,點(diǎn)擊后底部導(dǎo)航背景色將變化為此色
  this.backgroundColor,
})

使用方法如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyRootNavigationPage(),
    );;
  }
}

class MyRootNavigationPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _MyRootNavigationPage();
  }
}

class _MyRootNavigationPage extends State<MyRootNavigationPage> {

  final List<String> _pageTitles = <String>[
    "page 1",
    "page 2",
    "page 3"
  ];
  String _pageTitle;
  int _currentSelected = 0;
  final List<Widget> _pageWidget = <Widget>[
    _FirstPage(),
    _SecondPage(),
    _ThirdPage(),
  ];

  _itemSelected(int valueIndex) {
    setState(() {
      _currentSelected = valueIndex;
      _pageTitle = _pageTitles.elementAt(valueIndex);
    });
  }

  @override
  void initState() {
    super.initState();
    _pageTitle = _pageTitles.first;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("$_pageTitle"),
      ),
      body: Container(
        child: _pageWidget.elementAt(_currentSelected),
      ),
      endDrawer: Drawer(),
      bottomNavigationBar: BottomNavigationBar(
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.print),
            title: Text("Page1"),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.party_mode),
            title: Text("Page2"),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.add_a_photo),
            title: Text("Page3"),
          ),
        ],
        currentIndex: _currentSelected,
        onTap: _itemSelected,
        backgroundColor: Colors.yellowAccent,
        selectedItemColor: Colors.red,
        unselectedItemColor: Colors.black45,
      ),
    );
  }
}

class _FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("Page 1"));
  }
}

class _SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("Page 2"));
  }
}

class _ThirdPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("Page 3"));
  }
}

對(duì)于 BottomNavigationBarItem 內(nèi)的顯示圖標(biāo),可以使用 Image 加載自定義的圖片。上述代碼效果如下:

20203121058.jpg

BottomNavigationBartypeBottomNavigationBarType 類(lèi)型,是一個(gè)枚舉類(lèi)型,如下:

enum BottomNavigationBarType {
  //底部導(dǎo)航條的底部導(dǎo)航條有固定的寬度
  fixed,

  //底部導(dǎo)航欄底部導(dǎo)航欄的位置和大小動(dòng)畫(huà)和標(biāo)簽在被點(diǎn)擊時(shí)淡入
  shifting,
}

ScaffoldpersistentFooterButtonsList<Widget> 類(lèi)型,是一組顯示在 Scaffold 底部的 Widget ,通常使用 FlatButton 。這組 Widget 會(huì)呈現(xiàn)在 bottomNavigationBar 的上方,body 下方。他們是持續(xù)可見(jiàn)的,即使 body 進(jìn)行滾動(dòng)依然如此。使用方式如下:

persistentFooterButtons: <Widget>[
        FlatButton(onPressed: (){}, child: Text("按鈕1")),
        FlatButton(onPressed: (){}, child: Text("按鈕1")),
        FlatButton(onPressed: (){}, child: Text("按鈕1"))
      ],

效果如下圖:

20203121115.jpg

bottomSheet 對(duì)應(yīng)的是一個(gè) Widget ,是一個(gè)始終可見(jiàn)的 Widget ??梢杂脕?lái)定義底部的菜單或?qū)υ?huà)框。也可以使用 Flutter 提供好的

使用任意 Widget 的方法如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyFirstPage(),
    );;
  }
}

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page 1"),
      ),
      body: Container(
        color: Colors.yellow,
        child: Center(child: Text("主體內(nèi)容"),),
      ),
      bottomSheet: Container(    //bottomSheet
        color: Colors.red,
        height: 80,
        child: Center(child: Text("BottomSheet")),
      ),
      endDrawer: Drawer(),
    );
  }
}

效果如下圖:

2020313235.jpg

在底部展示消息還可以使用 SnackBar Widget ,其是一個(gè) StatefulWidget ,是一個(gè)輕量級(jí)的帶有可選操作的在屏幕底部暫時(shí)出現(xiàn)的 Widget。其構(gòu)造方法如下:

const SnackBar({
  Key key,
  //Widget類(lèi)型必傳參數(shù),要顯示的Widget
  @required this.content,
  //Color類(lèi)型可選命名參數(shù),用于指定背景色
  this.backgroundColor,
  //double類(lèi)型可選命名參數(shù),SnackBar的z坐標(biāo),這可以控制SnackBar下方陰影的大小
  this.elevation,
  //ShapeBorder類(lèi)型可選命名參數(shù),SnackBar的形狀
  this.shape,
  //SnackBarBehavior類(lèi)型可選命名參數(shù),用于設(shè)置SnackBar的行為和位置
  this.behavior,
  //SnackBarAction類(lèi)型可選命名參數(shù),要執(zhí)行的行為
  this.action,
  //Duration類(lèi)型可選命名參數(shù),SnackBar的持續(xù)顯示時(shí)間
  this.duration = _snackBarDisplayDuration,
  //Animation<double>類(lèi)型可選命名參數(shù),動(dòng)畫(huà)
  this.animation,
  //VoidCallback類(lèi)型可選命名參數(shù),第一次在Scaffold中出現(xiàn)時(shí)的回調(diào)函數(shù)
  this.onVisible,
})

使用如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyFirstPage(),
    );;
  }
}

class MyFirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Page 1"),
      ),
      body: Builder(
        builder: (BuildContext context){
          return Container(
            color: Colors.yellow,
            child: Center(
              child: RaisedButton(
                child: Text("SnackBar"),
                onPressed: (){
                  ScaffoldState state = Scaffold.of(context);
                  SnackBar snBar = SnackBar(
                    content: Text("這是一個(gè)提示信息"),
                    backgroundColor: Colors.deepPurpleAccent,
                    action: SnackBarAction(
                      label: "點(diǎn)擊查看詳情",
                      onPressed: (){
                        print("詳情內(nèi)容");
                      },
                    ),
                    onVisible: ()=> print("第一次出現(xiàn)執(zhí)行,僅執(zhí)行一次"),
                  );
                  state.showSnackBar(snBar);
                },
              ),
            ),
          );
        },
      ),
      endDrawer: Drawer(),
    );
  }
}

效果如下:

2020314732.gif

三、MaterialApp Widget 補(bǔ)充

MaterialApp 中的 themedarkTheme 均是 ThemeData 類(lèi)型,用于設(shè)置應(yīng)用的主題顏色和板式值??梢耘渲?ThemeMaterialApp Widget ,獲取當(dāng)前的主題,可以使用 Theme.of 。區(qū)別在于 darkTheme 意思是提供暗黑模式的主題,在設(shè)置 ThemeDataBrightness 時(shí)應(yīng)設(shè)置為 dark 。如果同時(shí)提供 themedarkTheme ,則可以設(shè)置 themeMode 進(jìn)行主題選擇,這就是同時(shí)提供兩種主題模式的用途,可以通過(guò)不同的設(shè)置提供不同的主題樣式。主題主要用來(lái)定義應(yīng)用程序通用的樣式和顏色基調(diào),可以再對(duì)不同的 Widget 做具體細(xì)節(jié)調(diào)整。其構(gòu)工廠(chǎng)造函數(shù)如下:

factory ThemeData({
  //Brightness類(lèi)型可選命名參數(shù),用于設(shè)置主題的模式,dark或者light
  Brightness brightness,
  //MaterialColor類(lèi)型可選命名參數(shù),用于定義一種單一的顏色,此顏色帶有始終色調(diào)的顏色樣本
  MaterialColor primarySwatch,
  //Color類(lèi)型可選命名參數(shù),用于設(shè)置工具欄、標(biāo)簽欄等的背景色
  Color primaryColor,
  //Brightness類(lèi)型可選命名參數(shù),在主題模式不變的情況下設(shè)置基色(工具欄等)的文本和圖標(biāo)反色
  Brightness primaryColorBrightness,
  //Color類(lèi)型可選命名參數(shù),原色的較輕版本
  Color primaryColorLight,
  //Color類(lèi)型可選命名參數(shù),原色的較暗版本
  Color primaryColorDark,
  //Color類(lèi)型可選命名參數(shù),小部件的前景色(旋鈕、文本、過(guò)卷邊緣效果等)
  Color accentColor,
  //Brightness類(lèi)型可選命名參數(shù),用于確定放置在強(qiáng)調(diào)色頂部的文本和圖標(biāo)的顏色(例如,浮動(dòng)操作按鈕上的圖標(biāo))
  Brightness accentColorBrightness,
  //Color類(lèi)型可選命名參數(shù),畫(huà)布顏色
  Color canvasColor,
  //Color類(lèi)型可選命名參數(shù),Scaffold的頁(yè)面背景色
  Color scaffoldBackgroundColor,
  //Color類(lèi)型可選命名參數(shù),底部應(yīng)用欄的默認(rèn)顏色
  Color bottomAppBarColor,
  //Color類(lèi)型可選命名參數(shù),Card的顏色
  Color cardColor,
  //Color類(lèi)型可選命名參數(shù),分隔線(xiàn)和彈出窗口的顏色也用于列表間、數(shù)據(jù)表中的行間等等
  Color dividerColor,
  //Color類(lèi)型可選命名參數(shù),使用的焦點(diǎn)顏色表示組件具有輸入焦點(diǎn)
  Color focusColor,
  //Color類(lèi)型可選命名參數(shù),用于指示指針何時(shí)懸停在組件上的懸停顏色
  Color hoverColor,
  //Color類(lèi)型可選命名參數(shù),高亮顏色
  Color highlightColor,
  //Color類(lèi)型可選命名參數(shù),InkWell顏色
  Color splashColor,
  //InteractiveInkFeatureFactory類(lèi)型可選命名參數(shù),定義墨水池和墨水響應(yīng)產(chǎn)生的墨水飛濺的外觀(guān)
  InteractiveInkFeatureFactory splashFactory,
  //Color類(lèi)型可選命名參數(shù),用于突出顯示選定行的顏色
  Color selectedRowColor,
  //Color類(lèi)型可選命名參數(shù),處于非活動(dòng)(但已啟用)狀態(tài)的小部件所用的顏色
  Color unselectedWidgetColor,
  //Color類(lèi)型可選命名參數(shù),不工作的小部件所用的顏色,與它們的狀態(tài)無(wú)關(guān)
  Color disabledColor,
  //Color類(lèi)型可選命名參數(shù),“凸起”按鈕中使用的材料的默認(rèn)填充顏色
  Color buttonColor,
  //ButtonThemeData類(lèi)型可選命名參數(shù),定義按鈕小部件的默認(rèn)配置,如上升按鈕和平板按鈕
  ButtonThemeData buttonTheme,
  //ToggleButtonsThemeData類(lèi)型可選命名參數(shù),定義ToggleButtons小部件的默認(rèn)配置
  ToggleButtonsThemeData toggleButtonsTheme,
  //Color類(lèi)型可選命名參數(shù),當(dāng)有選定行時(shí),分頁(yè)數(shù)據(jù)表的標(biāo)題顏色
  Color secondaryHeaderColor,
  //Color類(lèi)型可選命名參數(shù),文本字段中文本選擇的顏色,如文本字段
  Color textSelectionColor,
  //Color類(lèi)型可選命名參數(shù),TextField(如文本字段)等中光標(biāo)的顏色
  Color cursorColor,
  //Color類(lèi)型可選命名參數(shù),用于調(diào)整當(dāng)前所選文本部分的手柄顏色
  Color textSelectionHandleColor,
  //Color類(lèi)型可選命名參數(shù),與原色形成對(duì)比的顏色,例如用作進(jìn)度條的剩余部分
  Color backgroundColor,
  //Color類(lèi)型可選命名參數(shù),對(duì)話(huà)框元素的背景顏色
  Color dialogBackgroundColor,
  //Color類(lèi)型可選命名參數(shù),標(biāo)簽欄中所選標(biāo)簽指示器的顏色
  Color indicatorColor,
  //Color類(lèi)型可選命名參數(shù),用于提示文本或占位符文本的顏色,例如在文本字段中
  Color hintColor,
  //Color類(lèi)型可選命名參數(shù),用于輸入驗(yàn)證錯(cuò)誤的顏色,例如在文本字段中
  Color errorColor,
  //Color類(lèi)型可選命名參數(shù),用于突出顯示可切換小部件(如開(kāi)關(guān)、收音機(jī)和復(fù)選框)活動(dòng)狀態(tài)的顏色
  Color toggleableActiveColor,
  //String類(lèi)型可選命名參數(shù),用于設(shè)置字體名稱(chēng)
  String fontFamily,
  //TextTheme類(lèi)型可選命名參數(shù),文字顏色與卡片和畫(huà)布顏色
  TextTheme textTheme,
  //TextTheme類(lèi)型可選命名參數(shù),與原色形成對(duì)比的文本主題
  TextTheme primaryTextTheme,
  //TextTheme類(lèi)型可選命名參數(shù),與強(qiáng)調(diào)色形成對(duì)比的文本主題
  TextTheme accentTextTheme,
  //InputDecorationTheme類(lèi)型可選命名參數(shù),輸入編輯器、文本字段和文本表單字段的默認(rèn)輸入配置值基于此主題
  InputDecorationTheme inputDecorationTheme,
  //IconThemeData類(lèi)型可選命名參數(shù),與卡片和畫(huà)布顏色形成對(duì)比的圖標(biāo)主題
  IconThemeData iconTheme,
  //IconThemeData類(lèi)型可選命名參數(shù),與原色形成對(duì)比的圖標(biāo)主題
  IconThemeData primaryIconTheme,
  //IconThemeData類(lèi)型可選命名參數(shù),與強(qiáng)調(diào)色形成對(duì)比的圖標(biāo)主題
  IconThemeData accentIconTheme,
  //SliderThemeData類(lèi)型可選命名參數(shù),用于渲染滑塊的顏色和形狀
  SliderThemeData sliderTheme,
  //TabBarTheme類(lèi)型可選命名參數(shù),用于自定義標(biāo)簽欄指示器的大小、形狀和顏色的主題
  TabBarTheme tabBarTheme,
  //TooltipThemeData類(lèi)型可選命名參數(shù),用于自定義工具提示視覺(jué)屬性的主題
  TooltipThemeData tooltipTheme,
  //CardTheme類(lèi)型可選命名參數(shù),用于渲染卡片的顏色和樣式
  CardTheme cardTheme,
  //ChipThemeData類(lèi)型可選命名參數(shù),用于渲染芯片的顏色和樣式
  ChipThemeData chipTheme,
  //TargetPlatform類(lèi)型可選命名參數(shù),材料部件應(yīng)適應(yīng)目標(biāo)的平臺(tái)
  TargetPlatform platform,
  //MaterialTapTargetSize類(lèi)型可選命名參數(shù),配置某些材質(zhì)小部件的命中測(cè)試大小
  MaterialTapTargetSize materialTapTargetSize,
  //bool類(lèi)型可選命名參數(shù),在材質(zhì)表面應(yīng)用半透明疊加顏色,以指示深色主題的高度
  bool applyElevationOverlayColor,
  //PageTransitionsTheme類(lèi)型可選命名參數(shù),每個(gè)目標(biāo)平臺(tái)的默認(rèn)材質(zhì)頁(yè)面輸出轉(zhuǎn)換
  PageTransitionsTheme pageTransitionsTheme,
  //AppBarTheme類(lèi)型可選命名參數(shù),用于自定義應(yīng)用欄的顏色、高度、亮度、圖標(biāo)主題和文本主題的主題
  AppBarTheme appBarTheme,
  //BottomAppBarTheme類(lèi)型可選命名參數(shù),用于自定義底部工具欄的形狀、高度和顏色的主題
  BottomAppBarTheme bottomAppBarTheme,
  //ColorScheme類(lèi)型可選命名參數(shù),一組十三種顏色,可用于配置大多數(shù)組件的顏色屬性
  ColorScheme colorScheme,
  //DialogTheme類(lèi)型可選命名參數(shù),用于自定義對(duì)話(huà)框形狀的主題
  DialogTheme dialogTheme,
  //FloatingActionButtonThemeData類(lèi)型可選命名參數(shù),用于自定義浮動(dòng)動(dòng)作按鈕的形狀、高度和顏色的主題
  FloatingActionButtonThemeData floatingActionButtonTheme,
  //Typography類(lèi)型可選命名參數(shù),用于配置文本主題、主文本主題和重音文本主題的顏色和幾何文本主題值
  Typography typography,
  //CupertinoThemeData類(lèi)型可選命名參數(shù),要從“材料”主題“數(shù)據(jù)”自適應(yīng)中覆蓋的CupertinoThemeData的組件
  CupertinoThemeData cupertinoOverrideTheme,
  //SnackBarThemeData類(lèi)型可選命名參數(shù),用于自定義SnackBar的顏色、形狀、高度和行為的主題
  SnackBarThemeData snackBarTheme,
  //BottomSheetThemeData類(lèi)型可選命名參數(shù),用于自定義底部工作表的顏色、高度和形狀的主題
  BottomSheetThemeData bottomSheetTheme,
  //PopupMenuThemeData類(lèi)型可選命名參數(shù),用于自定義彈出菜單的顏色、形狀、高度和文本樣式的主題
  PopupMenuThemeData popupMenuTheme,
  //MaterialBannerThemeData類(lèi)型可選命名參數(shù),用于自定義材質(zhì)橫幅的顏色和文本樣式的主題
  MaterialBannerThemeData bannerTheme,
  //DividerThemeData類(lèi)型可選命名參數(shù),自定義分割線(xiàn)、垂直分割線(xiàn)等的顏色、厚度和縮進(jìn)的主題
  DividerThemeData dividerTheme,
  //ButtonBarThemeData類(lèi)型可選命名參數(shù),自定義按鈕欄小部件外觀(guān)和布局的主題
  ButtonBarThemeData buttonBarTheme,
})

關(guān)于 ThemeData 的不同屬性只是翻譯自官方文檔,部分沒(méi)有做驗(yàn)證看效果,各位要自己試驗(yàn)看效果。

locale 用于設(shè)置應(yīng)用程序的本地語(yǔ)言初始化環(huán)境值。如果為 null ,則使用系統(tǒng)的區(qū)域設(shè)置值。如果 Localizations.locale 的值與 supportedLocales 之一匹配,則它將等于該語(yǔ)言環(huán)境。 否則它將是第一個(gè) supportedLocale。

關(guān)于國(guó)際化的使用方式查看官方網(wǎng)址:https://flutter.dev/docs/development/accessibility-and-localization/internationalization 。后續(xù)文章也會(huì)詳細(xì)介紹。

上述說(shuō)的都是單獨(dú)的界面,如果涉及到頁(yè)面的切換,比如查看列表的詳細(xì)信息,進(jìn)入下一級(jí)等,需要使用到 Navigator Widget 。

Navigator 是使用堆棧規(guī)則管理一組 Widget ,這些 Widget (界面)稱(chēng)為 Route 對(duì)象 。其繼承自 StatefulWidget ,是一個(gè)有狀態(tài)的 Widget 。其構(gòu)造方法如下:

const Navigator({
  Key key,
  //String類(lèi)型可選命名參數(shù),要顯示的第一個(gè)路由(頁(yè)面)的名稱(chēng)
  this.initialRoute,
  //RouteFactory類(lèi)型必傳參數(shù),調(diào)用以生成給定路由設(shè)置的路由
  @required this.onGenerateRoute,
  //RouteFactory類(lèi)型必傳參數(shù),當(dāng)onGenerateRoute無(wú)法生成路由時(shí)調(diào)用
  this.onUnknownRoute,
  //List<NavigatorObserver>類(lèi)型必傳參數(shù),導(dǎo)航器的觀(guān)察者列表
  this.observers = const <NavigatorObserver>[],
})

在執(zhí)行路由線(xiàn)路切換需要使用 Navigatorpushpop 方法,如下:

//將制定路由添加到到導(dǎo)航的路由棧中
@optionalTypeArgs
static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {
  return Navigator.of(context).push(route);
}

//用于彈出最頂端的路由
@optionalTypeArgs
static bool pop<T extends Object>(BuildContext context, [ T result ]) {
  return Navigator.of(context).pop<T>(result);
}

Navigator.push() 接收兩個(gè)參數(shù),一個(gè)是上下文信息,另一個(gè)是 Route ,可以使用 MaterialPageRote的實(shí)例。其構(gòu)造函數(shù)如下:

MaterialPageRoute({
  //WidgetBuilder類(lèi)型必傳參數(shù),構(gòu)建路線(xiàn)的主要內(nèi)容
  @required this.builder,
  //RouteSettings類(lèi)型可選命名參數(shù),路由的設(shè)置
  RouteSettings settings,
  //bool類(lèi)型可選命名參數(shù),路由處于非活動(dòng)狀態(tài)時(shí)是否應(yīng)保留在內(nèi)存中
  this.maintainState = true,
  //bool類(lèi)型可選命名參數(shù),此頁(yè)面路由是否為全屏對(duì)話(huà)框。在iOS上,
  //這些頁(yè)面從底部到頂部(而不是水平)進(jìn)行動(dòng)畫(huà)處理。
  bool fullscreenDialog = false,
})

使用方式如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );;
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Builder(
        builder: (BuildContext context){
          return Container(
            color: Colors.yellow,
            child: Center(
              child: RaisedButton(
                child: Text("下一頁(yè)"),
                onPressed: (){
                 Navigator.push(context, MaterialPageRoute(
                   builder: (context) => FirstPage(),
                   fullscreenDialog: false,  //如果為true,則動(dòng)畫(huà)為從下至上推出
                 ));
                },
              ),
            ),
          );
        },
      ),
      endDrawer: Drawer(),
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FirstPage"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("上一頁(yè)"),
          onPressed: (){
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

效果如下:

2020315123.gif

也可以通過(guò)設(shè)置 Material.routes 來(lái)設(shè)置導(dǎo)航的頂級(jí)路由路線(xiàn),通過(guò) Navigator.pushNamed 方法進(jìn)行導(dǎo)航界面切換,pushNamed 方法原型如下:

@optionalTypeArgs
static Future<T> pushNamed<T extends Object>(
  //BuildContext類(lèi)型必傳參數(shù),上線(xiàn)文
  BuildContext context,
  //String類(lèi)型必傳參數(shù),路由路徑名稱(chēng)
  String routeName, {
  //Object類(lèi)型可選命名參數(shù),參數(shù)
  Object arguments,
 }) {
  return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
}

使用方式如下:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
      routes: {
        "/first" : (context)=> FirstPage(),
      },
    );;
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Builder(
        builder: (BuildContext context){
          return Container(
            color: Colors.yellow,
            child: Center(
              child: RaisedButton(
                child: Text("下一頁(yè)"),
                onPressed: (){
                  Navigator.pushNamed(context, "/first");
                },
              ),
            ),
          );
        },
      ),
      endDrawer: Drawer(),
    );
  }
}

class FirstPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FirstPage"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("上一頁(yè)"),
          onPressed: (){
            Navigator.pop(context);
          },
        ),
      ),
    );
  }
}

因?yàn)樵?home 中設(shè)置了首頁(yè),所以在 routes 中不需要設(shè)置 / 來(lái)表示首頁(yè),home 等同于 / 。

如果涉及到頁(yè)面?zhèn)髦?,正向傳值如果使?Navigator.push() ,可以使用被傳遞參數(shù)的 Widget 的構(gòu)造方法,使用Navigator.pushNamed() ,可以使用其第三個(gè)參數(shù) arguments 進(jìn)行參數(shù)設(shè)置。 反向可以使用 Navigator.pop 的參數(shù)進(jìn)行設(shè)置。如下:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Builder(
        builder: (BuildContext context){
          return Container(
            color: Colors.yellow,
            child: Center(
              child: RaisedButton(
                child: Text("下一頁(yè)"),
                onPressed: (){
                 //使用push
                 Navigator.push(context, MaterialPageRoute(
                   builder: (context) => FirstPage("hike"),
                   fullscreenDialog: false,
                 )
                 ).then((value){
                   print(value);
                 });
                },
              ),
            ),
          );
        },
      ),
      endDrawer: Drawer(),
    );
  }
}

class FirstPage extends StatelessWidget {

  FirstPage(this.userName);
  final String userName;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("FirstPage"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("上一頁(yè) 名字為:$userName"),
          onPressed: (){
            Navigator.pop(context, "返回給HomePage的值");
          },
        ),
      ),
    );
  }
}
class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("HomePage"),
      ),
      body: Builder(
        builder: (BuildContext context){
          return Container(
            color: Colors.yellow,
            child: Center(
              child: RaisedButton(
                child: Text("下一頁(yè)"),
                onPressed: () async {
                 final result = await Navigator.pushNamed(context, "/first", arguments: <String, String>{
                    "name" : "hike",
                    "age" : "20",
                  });
                 print(result);
                },
              ),
            ),
          );
        },
      ),
      endDrawer: Drawer(),
    );
  }
}

class FirstPage extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    RouteSettings setting = ModalRoute.of(context).settings;

    final Map args = ModalRoute.of(context).settings.arguments;
    print(setting.name);

    return Scaffold(
      appBar: AppBar(
        title: Text("FirstPage"),
      ),
      body: Center(
        child: RaisedButton(
          child: Text("上一頁(yè)"),
          onPressed: (){
            Navigator.pop(context, <String>["hike", "nick"]);
          },
        ),
      ),
    );
  }
}

在正向傳值中,使用 Navigator.pushNamed() 方法時(shí),參數(shù) arguments 參數(shù)為 Object 類(lèi)型,所以可以定義任意類(lèi)型參數(shù),也可以使用 class 等包裝參數(shù)進(jìn)行傳遞。當(dāng)在接收參數(shù)頁(yè)面接收參數(shù)時(shí),使用 ModalRoute.of 進(jìn)行獲取,其返回一個(gè)帶有參數(shù)的當(dāng)前路由。

在反向傳值時(shí),當(dāng)調(diào)用 Navigator.pop() 時(shí),會(huì)將其中的參數(shù)包裝到該方法返回的 Feature 對(duì)象中。后續(xù)文章會(huì)詳細(xì)介紹??梢圆榭垂俜秸f(shuō)明文檔:https://flutter.dev/docs/cookbook/navigation/returning-data

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容