現今來說,App 使用者介面往往有著類似的樣貌,這些樣貌是諸多使用者的經驗促成的,在對使用者介面沒有什麼特別想法的情況下,往往就會採用這類樣貌,這一方面也是為了避免造成使用者意料之外的行為,從而產生對 App 使用上的疑惑。
例如,不少 App 可能會有這樣的版面:
搭建這類版面的方式之一,是從頭到尾自行建構:
import 'package:flutter/material.dart';
void main() => runApp(
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Colors.blue,
height: 100,
child: Center(
child: Text(
'Flutter 筆記',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
)
),
),
Expanded( // 儘可能擴展元件填滿可用空間
child: Container(
color: Colors.white,
child: Text(
'內容...',
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.black)
),
)
),
Container(
color: Colors.cyan,
height: 80,
child: Center(
child: Text(
'版權...',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
)
),
)
]
)
);
因為這類佈局架構很常使用,或許你會想要定義一個通用的 AppScaffold
鷹架元件:
import 'package:flutter/material.dart';
void main() => runApp(
AppScaffold(
title: Text(
'Flutter 筆記',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
),
body: Text(
'內容...',
textDirection: TextDirection.ltr,
style: TextStyle(color: Colors.black)
),
footer: Text(
'版權...',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
),
)
);
class AppScaffold extends StatelessWidget {
final Widget title;
final Widget body;
final Widget footer;
AppScaffold({this.title, this.body, this.footer});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
color: Colors.blue,
height: 100,
child: Center(child: title),
),
Expanded(
child: Container(
color: Colors.white,
child: body,
)
),
Container(
color: Colors.cyan,
height: 80,
child: Center(child: footer),
)
]
);
}
}
隨著你建立的 App 越多,這個 AppScaffold
可能因不斷重用、重構而越來越通用,例如,可以自訂顏色、為了能有因應操作產生畫面變化,改繼承 StatefulWidget
等…
實際上,Flutter 就有個通用的 Scaffold
類別可以使用,必須搭配 MaterialApp
:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text(
'Flutter 筆記',
textDirection: TextDirection.ltr,
),
),
body: Text(
'內容...',
textDirection: TextDirection.ltr,
),
bottomNavigationBar: BottomAppBar(
color: Colors.cyan,
child: Text(
'版權...',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
)
),
),
)
);
執行結果如下:
Material Design 是一套設計指南,目的是為了介面設計可營造最佳的使用者經驗,簡單來說,對於平面螢幕裝置的介面設計(手機 App、Web 網頁,甚至是桌面應用程式),Material Design 主張不侷促於實體元件的模擬(例如在手機螢幕中模擬實體世界的立體按鈕),畢竟電子螢幕中的數位元素,本質上不存在於實體世界中,應該要去重新定義數位元素本身應有樣貌、彈性與屬性的一種設計。
MaterialApp
是個用來實作 Material Design 風格的支援類別,實際上至今使用的 material
套件中的元件也都是用來支援 Material Design。
Scaffold
是通用的鷹架元件,MaterialApp
是用來支援 Material Design,想當然爾,可設定的細節很多,例如,改變一下佈景主題:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
theme: ThemeData(
brightness: Brightness.dark,
primaryColor: Colors.yellow
),
home: Scaffold(
appBar: AppBar(
title: Text(
'Flutter 筆記',
textDirection: TextDirection.ltr,
),
),
body: Text(
'內容...',
textDirection: TextDirection.ltr,
),
bottomNavigationBar: BottomAppBar(
child: Text(
'版權...',
textDirection: TextDirection.ltr,
textAlign: TextAlign.center,
)
),
),
)
);
執行結果:
類似地,因為可設定的細節很多,單純談每個設定細節是極其無聊的一件事,日後有用到的場景,再做相關說明會是比較好的方式。