第一個 Flutter 專案


在〈準備 Flutter 開發環境〉建立的第一個 Flutter 專案,其中的範例程式碼被我無視到現在,現在可以稍微回頭看一下它了,首先看看:

import 'package:flutter/material.dart';

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

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

現在看這段很簡單了,runApp 接受的 MyAppStatelessWidget 子類,build 傳回了 MaterialApptitle 特性在 Android 的話,是在檢視「最近應用程式」時才會看得到,theme 是佈景主題設定,可以給予 MaterialApp 的元件整套的配色。

在〈準備 Flutter 開發環境〉說過,Android Studio 的範例專案運行後,右下有個 + 號按鈕,應用程式會顯示你按了幾次按鈕,按鈕按下會引發事件,而事件通常對狀態改變有關,保存狀態的 WidgetMyHomePage,也就是它繼承了 StatelfulWidget

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

MyHomePage 有對應的 _MyHomePageState

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,  // 註冊 onPressed 處理器
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), 
    );
  }
}

在這邊看到 FloatingActionButton,這會建立一個浮動按鈕,內含一個 + 號的 Icon,提示文字為 'Increment'onPress 註冊的是按下按鈕後要執行的函式 _incrementCounter,其中呼叫 setState,指定的回呼函式執行後會遞增 _counter

就現在來看這個範例,其實應該很簡單就可以看懂了吧!不過你可能會有問題的是,與〈自訂 StatefulWidget〉中實作 StatefulWidget 不同的是,MyHomePage 定義了建構式,命名參數上有個 key?這是幹嘛用的?

其實在這個範例專案中,這個 key 沒有什麼實際作用,因為 _MyHomePageStatebuild 建構的 Widget 中,並沒有子樹具有 StatefulWidget 的相關元件,在這個範例專案中,將建構式只定義為底下形式也是可以的:

class MyHomePage extends StatefulWidget {
  MyHomePage({this.title});
  ...

不過建構 StatefulWidget 時是否指定 key,牽涉到 Widget 樹與 Element 樹之間,是否因應 Widget 樹的重新調整,Element 樹也要重新調整,這之後再來談。