Day 16 | 第一个 Flutter 专案

昨天我们安装後有试跑一下 flutter run ,而今天我们就要来好好讲讲这个预设专案到底有什麽东西。

我们先从档案结构来说明一下

https://ithelp.ithome.com.tw/upload/images/20210929/2011290660QYCqHQPS.png

这里有几个比较重要的资料夹

  1. android
  2. ios
  3. lib
  4. test
  5. web

其中 android 及 ios 和 web 都是我们需要额外开启什麽功能或者打包相关的设定才有机会碰到,以我的经验就是一些有关版本及权限问题或者firebase相关的东西有去更动过里面的档案,不然应该是没什麽机会需要去动。

所以剩的就是 libtest 这两个资料夹。 test 是存放「测试」的资料夹像是Unit testing及Widget tests,而 lib 就是主要存放我们程序码的地方。

接下来让我们来了解一下 lib 里的 main.dart 到底做了哪些事情。

第一眼会先看到 main() 这个function它是整个 dart code 的进入点。
https://ithelp.ithome.com.tw/upload/images/20210929/20112906rXeRqJZ2hC.png

里面会执行一个function runApp ,简单来说runApp 就是将我们的 widget 绘制到萤幕上的一个API,所以里面放了一个 widget MyApp()

接下来看 MyApp 到底做了哪些事情。

https://ithelp.ithome.com.tw/upload/images/20210929/20112906JY2m9tu81x.png

首先看到 extends StatelessWidget ,说明了MyApp 是一个 StatelessWidget 。在 Flutter 中不考虑第三套件的话,UI相关widget基本上就是 StatelessWidgetStatefullWidget 这两种,它们最大的差异是一个有状态一个没有,至於什麽是「状态」我们等遇到了再好好说明。

说回到StatelessWidget
基本上我们的 widget 都是用 class 来宣告,所以会看到这个 MyApp 的 constructor

const MyApp({Key? key}) : super(key: key);

这里有一个optional named parameter Key? key ,这个 key 的作用基本上是为了确保重新渲染後widget 能够保持我们预期中的状态而设定的,但如果只是纯粹的UI显示而没有什麽CRUD的操作通常 key 是可以不用去管的。

接下来会看到 widget 中的重点

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }

这个 @override 就是要 implement 我们从 StatelessWidget (这是一个 abstract class)拿到的 build method 。

他的 return type 是 Widget 所以会看到我们在大括号中 return 了一个 MaterialApp,它包含了title、theme 及 route 的相关设定,而这里的 home 就是default route的意思,所以 home 接了一个widget MyHomePage

至於 router 参数之後的范例会在说明。

简而言之这算是一个 flutter/material 提供的一个App入口,如果你不用MaterialApp 是可以的但通常都会使用,即使不是用flutter/material 提供的也有可能会是其他第三方套件提供,像是 getx 就有一个 GetMaterialApp 作为入口。

继续往下看到 MyHomePage 的实作

https://ithelp.ithome.com.tw/upload/images/20210929/20112906GphbNcYlZj.png

会发现这时是 extends StatefulWidget 也就是所谓有「状态」的widget,有一个跟StatelessWidget 长的差不多的 constructor 然後多了一个 named parameter title 也就是接从上面 MaterialApp 传下来的 'Flutter Demo Home Page'

再来会看到 implement createState 这个 method ,但createState 要认真解释它到底做了哪些事情就要深入到flutter的渲染原理,所以这里只要知道他是创造StatefulWidget 的 instance时会呼叫的method 。

接下来看 _MyHomePageState 这东西,基本上可以想像成是这个 StatefulWidget UI描述及状态管理的集合体。

https://ithelp.ithome.com.tw/upload/images/20210929/20112906jNf0iviSXB.png

这里的 _counter 就是所谓的「状态」,我们可以透过 setState 来做更新状态,但到底什麽是「状态」,我觉得是一个我们在互动中所产生的暂时结果。依这个例子来说我按下按钮他会有一个结果来表示是现在的数字加一,但当我重新整理这一切会回到预设值。

而大部分有牵扯「状态管理」的程序通常就蕴含了我们怎麽更新状态数值、这个状态数值怎麽跟我们的画面连动等等议题。

StatefulWidget 来说,我们调用了setState 来更新一个值时,会有一个流程将新的结果渲染到画面上。所以当你把 setState 拿掉。只剩这样时

 void _incrementCounter() {
      _counter++;
  }

你会发现画面怎麽按都不会更新。
至於 build 里的东西,主要都是UI显示相关的事情,就留到明天与其他常用widget一起说明了。


<<:  Day14-Kubernetes 那些事 - Deployment 与 ReplicaSet(二)

>>:  【Day 16】深度学习(Deep Learning)--- Tip(一)

初学者跪着学JavaScript Day20 : 原型毕露(中)

一日客语:中文:青色 客语:抢厶ㄟ ˋ 继续学习原型吧~ 学习内容: 1.Object.getPro...

第15章:管理与设定网路介绍(二)

前言 本章节,是要讲述如何查看网路设定与设定在主机上的网路资讯。 识别与取得网路介面资讯 在一台主机...

[Vue2Leaflet系列二] Leaflet Plugins with Vue

本篇文章请参考 [Vue2Leaflet系列一] 从vue-cli安装到建置地图 之前介绍过Leaf...

Day 16 Simple Network Management Protocol (SNMP) 相关安全

Simple Network Management Protocol (SNMP) SNMP 简易网...

Day 12. 生命周期 - Lifecycle Hooks

Instance Lifecycle 生命周期 介绍完怎麽建立Vue instance 後,接着来谈...