前言

熟悉了dart语言的语法后,就准备开始进行实际操作了 ,首先是对demo程序代码的研究与学习
官方中文教程

① 起步

Demo程序计数器

从第一行
import 'package:flutter/material.dart';
中可以看出
dart语言中导入包是使用关键字import

Material UI组件库

Material是一种标准的移动端与web端的视觉设计语言,Flutter提供了一套丰富的Material风格的UI组件

void main() => runApp(MyApp());
与C/C++、Java类似,Flutter 应用中main函数为应用程序的入口

runApp()

runApp()函数接受一个Widget参数在计数器Demo中其是一个MyApp对象

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      //应用名称  
      title: 'Flutter Demo', 
      theme: new ThemeData(
        //蓝色主题  
        primarySwatch: Colors.blue,
      ),
      //应用首页路由  
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

MyApp

MyApp类代表Flutter应用,其继承了StatelessWidget类,这就意味着应用本身也是个Widget
其实在Flutter中大部分东西都是widget,包括

  • 对齐(alignment)
  • 填充(padding)
  • 布局(layout)

build()

Flutter在构建页面时,会调用组件的build方法,widget的主要工作是提供一个build()方法来描述如何构建UI界面

MaterialApp

是Material库中提供的Flutter APP框架,也是一个Widget

home

home是flutter应用的首页,也是一个widget

class MyHomePage extends StatefulWidget {
     MyHomePage({Key key, this.title}) : super(key: key);
     final String title;
     @override
     _MyHomePageState createState() => new _MyHomePageState();
   }

   class _MyHomePageState extends State<MyHomePage> {
    ...
   }

StatefulWidget

继承自该类的组件是有状态的组件(Stateful widget)

有状态的组件(Stateful widget)

  • 可以拥有状态,这些状态在widget生命周期中是可以变得
  • 至少由两个类组成
    • 一个StatefulWidget 类
    • 一个State类,StatefulWidget类本身是不变的,但是State类中持有的状态在widget生命周期中可能会发生变化
Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }

Scaffold

是Material库中提供的页面脚手架,其提供了默认的导航栏,标题和包含主屏幕widge树的body属性
21.PNG

之后的内容我用我的WeChatApp开发经验(巨菜)来仔细分析一下

appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),

这里是一个导航栏,标题为当前界面的title,因为在前面MyApp中有对title进行了实例化
home: MyHomePage(title: 'Flutter Demo Home Page'),
因此这里对其引用是有效的

Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),

这两个Text应该就是定义的文本了,也就是界面中央的两行文本,第一行是固定文本,而第二行也就是计数器的数值,因为要随着点击按钮的次数而变化,因此需要绑定变量,在这里它就绑定了一个变量_counter,而这个变量每当调用一次_incrementCounter()就会+1 ,而再将按钮的触发事件设为该函数,从而实现了按钮点击数值+1的功能

 floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.

其中的onPressed类似HTML中的onclick,也就是设置按钮的点击事件,至于child是什么目前还不知道,只知道其参数是一个图标(Icon)对象

接下来开始对布局相关代码做分析
body: Center(
Center组件,可以将其子组件树对齐到屏幕中央

child: Column(
Column组件的作用是将其所有子组件沿着屏幕垂直方向依次排列,上文中有提到,因为其子组件是两个Text组件,因此这两个Text组件就被放置在了屏幕中央,并且沿屏幕垂直方向依次排列

注意事项

  • build方法要放置在State中
    • 因为倘若StatefulWidget有很多状态,而每次状态改变都要调用build方法,状态是保存在build中的,如果真的将build方法放在StatefulWidget中,优于构造用户界面过程需要依赖Statem所以build方法必须加上一个State参数,这样的话只能置State所有状态为公开状态,将会导致对状态的修改不可控,状态将不具有私密性
    • 继承StatefulWidget不便

② 路由管理

按照官方教程,新建了一个页面并成功建立路由

新页面代码(是一个StatelessWidget)

class NewRoute extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text("new pages!"),
      ),
      body: Center(
      child: Text('this is a maza'),
      ),
    );
  }
}

随后在我们先前完成的主页面代码中的子组件中添加一个FlatButton

 FlatButton(
              child: Text("click here for more information"),
              textColor: Colors.red,
              onPressed: (){
                Navigator.push(context, MaterialPageRoute(builder: (context){
                  return NewRoute();
                }));
              },
            )

完成代码添加后重新加载程序
22.PNG
可以发现主界面重多了一行字,点击该行就会跳转到我们编写的新界面了
23.PNG

MaterialPageRoute

继承自PageRoute类,PageRoute是一个抽象abstract类(学过Java的大佬应该更了解),表示占有整个屏幕空间的的一个模态路由界面,还定义了路由构建及切换时过渡动画的相关接口及属性

而MaterialPageRoute是Material组件库提供的组件,针对不同平台实现与平台页面切换动画风格一致的路由切换动画

具体动画细节详见官方教程,这里不多加CV

  MaterialPageRoute({
    WidgetBuilder builder,
    RouteSettings settings,
    bool maintainState = true,
    bool fullscreenDialog = false,
  })

1. builder

是一个`WidgetBuilder类型的回调函数,其作用是构建路由页面的具体内容,返回值是一个widget,通常实现此回调来返回新路由的实例

2. settings

路由的配置信息

3. maintainState

如果想在路由没用的时候释放其所占用所有资源,可以设置该参数为false

4. fullscreenDialog

表示新的路由界面是否为一个全屏的模态对话框

是一个路由管理的组件,提供了打开与退出路由页的方法,其通过一个栈来管理活动路由的集合
通常当前屏幕现实的页面就是栈顶的路由

Future push(BuildContext context, Route route)

将给定的路由入栈(打开新界面),返回值是一个Future对象,用来**接收新路由出栈(关闭)返回的数据

bool pop(BuildContext context, [ result ])

话u不过栈顶路由出栈,result为页面关闭时返回给上一个页面的数据

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议