如需转载,请注明出处:Flutter学习笔记(15)–MaterialApp应用组件及routes路由详解

最近一段时间生病了,整天往医院跑,也没状态学东西了,现在是好了不少了,也该继续学习啦!!!

今天给大家讲一下MaterialApp应用组件及routes路由详解,我会着重说一下routes路由的使用及解释,因为会经常用到,前面我写的一些demo所涉及到的组件,都是遵循着Material Design设计风格,所谓的Material Design是由Goodle推出的全新的设计语言,这种设计旨在为手机、平板电脑、台式机和其他平台更一致、更广泛的外观和感觉,接下来我们看一下常见的Material Design风格组件:

Material Design风格组件说明
组件名称 中文名称 简单说明
Appbar 应用按钮组件 应用的工具按钮
AlertDialog 对话框组件 有操作按钮的对话框
BottomNavigationBar 底部导航组件 底部导航条,可以很容易的在tab之间切换和浏览顶级试图
Card 卡片组件 带有边框阴影的卡片组件
Drawer 抽屉组件 Drawer抽屉组件可以实现类似抽屉拉开关闭的效果
FloatingActionButton 悬浮按钮组件 应用的主要功能操作按钮
FlatButton 扁平按钮组件 扁平化风格的按钮
MaterialApp Material应用组件 MaterialApp代表使用纸墨设计风格的应用
PopupMenuButton 弹出菜单组件 弹出菜单按钮
Scaffold 脚手架组件 实现了基本的Material Design布局
SnackBar 轻量提示组件 一个轻量消息提示组件,在屏幕的底部显示
SimpileDialog 简单对话框组件 简单对话框组件。只起提示作用,没有交互
TabBar 水平选项卡及视图组件 一个显示水平选项卡的Material Design组件
TextField 文本框组件 可以接受应用输入文本的组件

Material Design风格的组件有这么多,不看不知道,一看吓一跳,这基本上都没有用过呀,漫漫长征路,还有很远要走呀,一个一个学吧!!!

MaterialApp(应用组件)

MaterialApp组件属性及描述
属性名 类型 说明
title String 应用程序的标题,该标题出现在如下位置Android:任务管理器的程序快照之上,iOS:程序切换管理器中
theme ThemeData 定义应用所使用的主题颜色,可以制定一个主题中每个控件的颜色
color Color 应用的主要颜色值,即primary color
home Widget 这个是一个Widget对象,用来定义一个主题中每个控件的颜色
routes Map<String,WidgetBuilder> 定义应用中页面跳转的原则
initialRoute String 初始化路由
onGenerateRoute RouteFactory 路由回调函数,当通过Nacigator.of(context).pushNamed跳转路由时,在routes查找不到时,会调用该方法
onLocaleChanged   当系统需改语言的时候,会触发这个回调
nagavitorObserver List<NavigatorObserver> 导航观察器
debugShowMaterialGird bool 是否显示纸墨设计基础布局网格,用来调试UI的工具
showPerformanceOverlay bool 显示性能标签

具体看下代码应用:

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

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

class DemoApp extends StatelessWidget{
  //这个是整个应用的主组件
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new MaterialApp(
      title: 'MaterialApp示例',
      debugShowMaterialGrid: true,
      showPerformanceOverlay: true,
      theme: new ThemeData(
        primaryColor: Colors.deepOrange
      ),
      home: new MaterialAppDemo(),
    );
  }
}

class MaterialAppDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: new AppBar(
        title: Text('MaterialAppDemo'),
      ),
      body: new Center(
        child: new Text('MaterialAppDemo'),
      ),
    );
  }
}

效果图:

Flutter学习笔记(15)–MaterialApp应用组件及routes路由详解-风君雪科技博客                        Flutter学习笔记(15)–MaterialApp应用组件及routes路由详解-风君雪科技博客

demo里面我主要尝试了title、theme、home、debugShowMaterialGird、showPerformanceOverlay属性,根据截图,给大家直观的对比一下结果:

title:应用程序的标题(因为我只有Android测试机),可以看到第二张截图,切到任务管理器,应用程序的标题为MaterialApp示例

theme:我用theme更改了应用主题的颜色,可以看到第一张截图导航栏的颜色改为了橙色。

home:home代表着整个页面的主widget,可以理解为根widget,而home的主体就是一个Center容器组件,然后里面放一个文本。

debugShowMaterialGird:这个属性我们设置为了true,页面展示出来会有很多网格,用于调试UI(这个要怎么用来调试UI,小弟还不会。。。)

showPerformanceOverlay:性能标签,这个设置为true,在页面的最上方会出现一些性能相关的数据。

routes(路由处理)

routes对象是一个Map<String,WidgetBuilder>,当使用Navigator.pushName来路由的时候,会在routes查找路由的名字,然后使用对应的WidgetBuilder来构造一个带有页面切换动画的MaterialPageRoute

下面我着重讲一下routes路由处理,因为我觉得页面间的跳转是最常用到的,而且很重要,下面的demo主要功能是在A页面点击一个按钮跳转到B页面,并且两个页面间传值。

注:路由跳转分静态路由跳转和动态路由跳转,两者的区别就是是否给第二个页面传值

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

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

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new MaterialApp(
      title: 'theme Title',
      debugShowMaterialGrid: false,
      home: new Scaffold(
        appBar: new AppBar(
          leading: Icon(Icons.menu),
          actions: <Widget>[
            Icon(Icons.search)
          ],
          title: new Text('routes demo'),
        ),
        body: new Center(
          child: new Text('主页'),
        ),
      ),
      routes: {
        '/first':(BuildContext context) => new FirstPage(),
        '/second':(BuildContext context) => new SecondPage(""),
      },
      initialRoute: '/first',//初始化路由为first页面
    );
  }
}

class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('First Page'),
      ),
      body: new Center(
        child: RaisedButton(
          child: new Text('第一个页面'),
            onPressed: (){
                //静态路由跳转,不给第二个页面传值
//              Navigator.pushNamed(context, '/second').then((value){
//                Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM);
//              });
              //动态路由跳转,给第二个页面传值
              Navigator.of(context).push(new MaterialPageRoute(builder: (context){
                return new SecondPage('这是从第一个页面传递出去的数据');
              })).then((value){
                Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM);
              });
            }
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  var content = '';
  SecondPage(this.content);

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Second Page'),
      ),
      body: new RaisedButton(
        child: new Text(content),
          onPressed: (){
//            Navigator.pop(context);//不给上一级页面返回参数
            Navigator.of(context).pop("这个是从第二个页面返回的数据");//给上一级页面返回参数
          }
      ),
    );
  }
}

效果截图:

Flutter学习笔记(15)–MaterialApp应用组件及routes路由详解-风君雪科技博客   Flutter学习笔记(15)–MaterialApp应用组件及routes路由详解-风君雪科技博客   Flutter学习笔记(15)–MaterialApp应用组件及routes路由详解-风君雪科技博客

来细讲一下上面的代码吧,要不然还真容易看懵逼了。

1.首先初始化路由列表,为后面页面跳转做准备,路由列表对应这每一个页面

routes: {
        '/first':(BuildContext context) => new FirstPage(),
        '/second':(BuildContext context) => new SecondPage(""),
      },

2.静态路由跳转,静态由A页面跳转到B页面,不给B页面传值,但是接收B页面返回的数据,并将返回值toast出来,即图3

Navigator.pushNamed(context, '/second').then((value){
                Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM);
              });

3.动态路由跳转,A页面跳转到B页面,并给B页面传值,将B页面的按钮文案赋值,从B页面返回后,将B页面的返回值toast出来,即图2,图3

Navigator.of(context).push(new MaterialPageRoute(builder: (context){
                return new SecondPage('这是从第一个页面传递出去的数据');
              })).then((value){
                Fluttertoast.showToast(msg: value,toastLength: Toast.LENGTH_LONG,gravity: ToastGravity.BOTTOM);
              });

4.由B页面带数据返回到A页面(页面Pop返回有两类,一类带参数返回,一类不带参数返回)

4.1带参数返回

Navigator.of(context).pop("这个是从第二个页面返回的数据");//给上一级页面返回参数

4.2不带参数返回

Navigator.pop(context);//不给上一级页面返回参数

注:页面Pop还有两个方法常用到

Navigator.canPop(context);//页面是否可以pop,返回bool值,可以用作页面判断
Navigator.maybePop(context);//如果当前页面可以pop,则会执行,反之则不会执行,更安全

以上就是今天的全部内容了,稍微难一点的就是路由这块儿了,我写的demo还是很简单的,页面跳转传值只是字符串,在项目中还会遇到其他类型的数据参数,暂时就先不研究了,等用到的时候在具体细看吧,上面的内容,如果各位有任何疑问,或者发现有错误的地方,还望留言!!!

下一章节:Flutter学习笔记(16)–Scaffold脚手架、AppBar组件、BottomNavigationBar组件