Scaffold
的 appBar
特性,可以用來設置頂端工具列,在之前的文件中,只都有隨便塞個 AppBar
實例,設置一下文字標題罷了,那麼 appBar
是什麼呢?如果查詢 API 文件,會發現 appBar
的型態不過就是 PreferredSizeWidget
。
PreferredSizeWidget
只有一個 preferredSize
取值方法(Getter)要實現,傳回的 Size
實例,是這個 Widget
的偏好尺寸,也就是可以的話,請使用這個尺寸的資訊,作為佈局的參考依據。
例如,稍後會看到,AppBar
本身也可以設置一個 bottom
元件,如果你設置了 bottom
元件,當然會希望 AppBar
的高度,至少有 bottom
元件的大小吧!
因此,如果有設置 bottom
的話,AppBar
會參考 bottom
的 preferredSize.height
資訊(bottom
接受的型態也是 PreferredSizeWidget
),加上 kToolbarHeight
(56 像素),作為它的 AppBar
的偏好高度;如果沒有 bottom
,或 bottom.preferredSize
沒設,或沒有 bottom.preferredSize.height
,那 AppBar
偏好高度就是 56,也就是使用 kToolbarHeight
。
如果 Scaffold
設置了 appBar
,則會用 appBar.preferredSize.height
加上頂端墊充作為高度。
既然如此,就表示只要實作 PreferredSizeWidget
,就可以把任何自訂的元件,指定給 appBar
了,例如,來隨便自訂一個簡單的頂端文字列:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: Scaffold(
appBar: TextTitle('openhome.cc'),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset('images/caterpillar.png'),
),
Text('我是一隻弱小的毛毛蟲,想像有天可以成為強壯的挖土機,擁有挖掘夢想的神奇手套!')
],
),
),
)
);
class TextTitle extends StatelessWidget implements PreferredSizeWidget {
final text;
TextTitle(this.text);
@override
Widget build(BuildContext context) {
return Container(
child: Center(
child: Text(
text,
style: TextStyle(
fontSize: 28,
color: Colors.white,
)
)
),
color: Colors.blue,
);
}
@override
Size get preferredSize => Size.fromHeight(kToolbarHeight);
}
執行結果如下:
當然,這是在 Flutter 提供的 AppBar
或 TabBar
(它們都實作了 PreferredSizeWidget
)無法滿足需求時,才需要做的事,這邊先來看 AppBar
,理解它作用最重要的就是 API 官方文件中這張圖:
leading
、title
、flexibleSpace
接受的都是 Widget
,actions
的型態是 List<Widget>
,也就是一組 Widget
,bottom
如前所述,可以是實作了 PreferredSizeWidget
的元件。
只要符合各特性接受的型態,基本上想放什麼就都是個人自由了,例如,leading
常會放個具有 Icons.menu
的按鈕之類的元件,表示可以展開選單;title
就是之前常用的了,通常會放個文字,不過想放個圖基本上也沒問題;actions
大概是這個頁面的常用操作,可以是使用特定圖示外觀之類的按鈕;bottoms
我想到的是可用在展示圖片時,顯示目前是在第幾張圖片,像是分頁指示之類的東西,或者你要把 TabBar
塞進去,實作個頂端的分頁導覽也行;flexibleSpace
就彈性應用吧!
底下的範例,純綷就目前學過的東西,塞到 AppBar
裏做些畫面上的展示,其中 TabBar
的使用,之後會再談,先看看外觀就好:
import 'package:flutter/material.dart';
void main() => runApp(
MaterialApp(
home: DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(
Icons.menu,
color: Colors.white,
),
onPressed: () => print('按下選單'),
),
title: Text('Openhome.cc'),
actions: [
IconButton(
icon: Icon(
Icons.pets,
color: Colors.white,
),
onPressed: () => print('按下狗掌'),
),
IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () => print('按下搜尋'),
)
],
bottom: TabBar(
tabs: [
Tab(text: 'Java'),
Tab(text: 'Python'),
Tab(text: 'JavaScript'),
],
),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Center(
child: Image.asset('images/caterpillar.png'),
),
Text('我是一隻弱小的毛毛蟲,想像有天可以成為強壯的挖土機,擁有挖掘夢想的神奇手套!')
],
),
),
)
)
);
執行後的畫面如下: