在網頁開發的過程裡,我們習慣會使用div
作為一個容器,因為在 html 語意上它是不特別代表任何東西的容器,因此通常會用它來進行一些 css 樣式的使用。在 flutter 裡也有一個類似div
的組件: Container
,它本身提供了許多參數設定可以用來設定padding
、margin
、border
、transform
...等效果。
學習 Widgets
Container
是一個很常使用的組件,我們看一下Container
的原始碼可以發現,它提供了許多樣式設定上常使用的屬性,在進行佈局排版的過程很適合用來當作 Flutter 的 Box Model
包裝其他組件。
class Container extends StatelessWidget {
Container({
Key? key,
this.alignment,
this.padding,
this.color,
this.decoration,
this.foregroundDecoration,
double? width,
double? height,
BoxConstraints? constraints,
this.margin,
this.transform,
this.transformAlignment,
this.child,
this.clipBehavior = Clip.none,
})
從範例來看,我們在一張Image
包裝在一個大小為200x150的區塊,設定外距20.0、內距20.0,以及定義背景色以及邊框效果,再加上transform
轉移角度,就完成類似相框的效果。
var body = Column(
children: [
Center(
child: Container(
constraints: BoxConstraints.tightFor(
width: 200.0,
height: 150.0,
),
padding: EdgeInsets.all(1.0),
margin: const EdgeInsets.all(20.0),
decoration: BoxDecoration(
color: Color(0xFFFFE3D4),
border: Border.all(
color: Color(0xFFffd700),
width: 2,
),
borderRadius: BorderRadius.circular(4),
),
transform: Matrix4.rotationZ(0.1),
child: Image.asset(
"assets/images/xFrame.jpg",
),
),
),
],
);
Image 使用xframe圖庫的照片
Scaffold
應該是我們在學習 Flutter 過程中最常使用的容器組件,它提供了一個 App 畫面佈局的骨架,可以自訂義 AppBar (標題)、Drawer(抽屜選單)、BottomNavigationBar(導欄功能)這些App上常見的layout配置。
return Scaffold(
key: scaffoldKey,
appBar: appBar,
drawer: drawer,
body: body,
bottomNavigationBar: bottomNavigationBar,
);
因此下面我們就來試看看如何在 Scaffold
這個容器上新增選單功能吧。
Drawer
提供左側的抽屜選單容器位置,我們使用 ListView
與 ListTile
建立選單內容。
var drawer = Drawer(
child: ListView(
children: [
Container(
color: Colors.red,
height: 50,
child: Center(
child: Text(
"抽屜選單",
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
ListTile(
leading: Icon(Icons.exit_to_app),
title: Text('EXIT'),
onTap: () => Navigator.pop(context),
),
],
),
);
Drawer
提供了一個左側選單的容器空間,可以根據自己的需要定義這邊空間內的組件佈局。
BottomNavigationBar
提供底部導覽列的佈局功能,結合BottomNavigationBarItem
的設定可以加上想要 icon 按鈕。
var bottomNavigationBar = BottomNavigationBar(
items: [
BottomNavigationBarItem(icon: Icon(Icons.home_outlined), label: "首頁"),
BottomNavigationBarItem(
icon: Icon(Icons.add_a_photo_outlined), label: '相機'),
BottomNavigationBarItem(
icon: Icon(Icons.bug_report_outlined), label: "bug"),
],
currentIndex: _index,
onTap: (index) {
setState(() {
_index = index;
});
if (index == 0) {
Navigator.pop(context);
}
},
);
容器化的佈局組件很適合用來對 App 主要框架的佈局作定義,讓我們在特定的佈局位置上定義想要的內容。