昨天真的比較忙,文章寫得非常粗糙,但今天會一口氣彌補回來的!
void main() {
runApp(MyApp());
}
昨天有提到這裡是整個 APP 的進入點,那在 runApp 裡包著一個 MyApp(),代表在執行 runApp 時會執行 MyApp 的 Function ,那這裡我們先將其拿掉,替換為下列以下程式碼。
void main() {
runApp(
Center(
child: Text(
'Hello, world!',
textDirection: TextDirection.ltr,
),
),
);
}
此時進行加載,執行的結果應該會如下
這段程式在幹嘛呢?別急,先來複習一下,前幾天有提到 Flutter 的特性就是各個元件組合起來,有點像是樂高的概念。
元件基本上可以分成兩種類型:
1.可視元件 (visible widget):
可以直接看到的元件,通常如 Text、Icon、Button、Image等,簡單地說看的到的實體都可以算是 可視元件。
2.佈局元件 (layout widget):
用來輔助可視元件的東西,有點像是置物櫃或格子的概念,透過 佈局元件 來規劃可視元件的位置,所以也稱作容器。
說到這裡,就可以理解 runApp 裡面包覆著 Center 元件,看到 Center 應該不難猜出其實就是 佈局元件吧!而 Center 裡包覆的就是小零件 Text,其 textDirection (文字流向) 屬性為 ltr (left to right),內容為 'Hello, world!'。
好,那我們再更改為剛開始的 MyApp(),準備進入底下的 MyApp 的介紹。
首先先放上程式碼
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue, //設定主題顏色
visualDensity: VisualDensity.adaptivePlatformDensity, //自動適應任意畫面大小
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
我們可以看到這是一個 class (類別),繼承了 StatelessWidget (無狀態元件),那既然是繼承,代表這個 class 是屬於 StatelessWidget 類的,但卻又不是完全的一模一樣,這可以說是一個子類別,繼承了 StatelessWidget 這位老爸優秀的基因,但是兒子不會跟老爸完全一樣,所以會需要用 override 來進行覆寫,讓政府機關(程式)知道你跟你爸是兩個不同的人XD,才可以共享部分 福利 (程式碼),但是 銀行帳戶 (程式之間的訊息) 還是各自持有,不會互相影響。
緊接著的便是最重要的 繪製元件 的部分啦, Widget build 就是繪製元件啦,那在其中的 BuildContex 牽扯到太多的內容要說,這裡先簡單帶過,簡單地說, BuildContex 就是 Widget 對應的 Element,讓我們可以很快速地調用Element 類的東西。
return MaterialApp(),則是用來回傳 MaterialApp 類型的參數,裡面有標註了 title 的文字內容、ThemeData的相關參數,並且在 home 的區塊之中呼叫 MyHomePage 並傳值進去,這裡將 title 的值傳進去。
接著來看看可以 _ 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.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
負責處理計數的就是 incrementCounter() 這一段,裡面有著更新整個頁面的 Widgets 的 setState(),沒錯,就是調用他然後全部更新屬於 StatefulWidget的。
最後,來看看 Widget build 裡的葫蘆到底賣甚麼吧!
但在觀看之前,可以先到這裡觀看更多有趣的元件 (連結)
是一個容器元件,提供了 appBar 、drawers 、snack bars、bottom sheets等功能,可以有效的提供我們快速建置頁面的功能,不用再重頭的開發起,相對於開發人員來說是很方便的功能,那緊接著就來嘗試在 Scaffold 新增點東西試試看吧。
首先是 AppBar,以往都只有使用到顯示文字,但其實 AppBar 功能可多了,根據官方的說明顯示
還有著 leading、actions、flexibleSpace、bottom都沒使用到!
也是一個容器元件,但與 Scaffold 不一樣的點是,Container 是一個自由大小的容器,但只有一格,就像櫃子一樣,可以透過 alignment 調整位置,並且透過 color 來設定顏色,這裡給一個範例。
body:Container(
alignment: Alignment.center,
color: Colors.green,
child: Text('Container'),
)
此時執行後畫面應該都是綠色的一片,中間有個 Container 字樣。
還是一個容器元件,屬於水平的格子,可以透過 Expanded方式來新稱水平欄位。
body: Row(
children: <Widget>[
Expanded(
child: Text('Row1', textAlign: TextAlign.center),
),
Expanded(
child: FittedBox(
fit: BoxFit.contain, // otherwise the logo will be tiny
child: const FlutterLogo(),
),
),
Expanded(
child: Text('Row3', textAlign: TextAlign.center),
),
],
)
執行後應該會長這樣。
還有很多元件無法一一介紹,那就讓各位去嘗試摸索玩看看啦,那明天開始有用到新的元件會再介紹,就這樣!