在Flutter中,AppBar由一个工具栏和其他潜在的Widget组成。特别是AppBar分为五个区域,即前道,标题,工具栏(动作),flexiableSpace
和底部。
AppBar构造函数:
AppBar( {Key key,
Widget leading,
bool automaticallyImplyLeading: true,
Widget title,
List<Widget> actions,
Widget flexibleSpace,
PreferredSizeWidget bottom,
double elevation,
Color shadowColor,
ShapeBorder shape,
Color backgroundColor,
Brightness brightness,
IconThemeData iconTheme,
IconThemeData actionsIconTheme,
TextTheme textTheme,
bool primary: true,
bool centerTitle,
bool excludeHeaderSemantics: false,
double titleSpacing: NavigationToolbar.kMiddleSpacing,
double toolbarOpacity: 1.0,
double bottomOpacity: 1.0,
double toolbarHeight
}
)
通常通过Scaffold.appBar
属性将AppBar放入Scaffold中。AppBar将具有固定的高度,并显示在Scaffbar
的顶部。如果要使用可滚动的应用栏,请使用SliverAppBar
。
1. title
Widget title;
例如,一个简单的AppBar由放置在Scaffold
中的标题组成,它会出现在Scaffold
的顶部。
示例代码
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppBar Title"),
),
body: Center(
child: Text(
'Hello World',
)
),
);
}
}
标题居中或右对齐的AppBar的示例效果如下:
AppBar(
title: Align (
child: Text("AppBar Centered Title"),
alignment: Alignment.center
)
);
AppBar(
title: Align (
child: Text("AppBar Right Title"),
alignment: Alignment.centerRight
)
);
AppBar(
title: Text("AppBar Centered Title"),
centerTitle: true,
);
创建由图标和文本组成的“标题窗口小部件”的示例代码如下:
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: IconTitleWidget()
),
body: Center(
child: Text(
'Flutter AppBar Tutorial',
)
),
);
}
}
class IconTitleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
imageCache.clear();
return Row (
mainAxisAlignment: MainAxisAlignment.center, // Centers horizontally
crossAxisAlignment: CrossAxisAlignment.center, // Centers vertically
children: <Widget>[
Icon(Icons.train),
Icon(Icons.place),
// The SizedBox provides an immediate spacing between the widgets
SizedBox (
width: 3,
),
Text(
"Place",
)
],
);
}
}
2. 标题标头
标头是放置在标题区域前面的小部件。标头通常是一个Icon
或IconButton
。
Widget leading;
例如,前导是一个IconButton
。当用户单击IconButton
时,将执行某些操作。
// Example: leading is an IconButton
appBar: AppBar(
title: Text("AppBar Title"),
leading: IconButton(
icon: Icon(Icons.notifications_active),
onPressed: () {
// Do something.
}
)
)
// Example: leading is an Icon
appBar: AppBar(
title: Text("AppBar Title"),
leading: Icon(Icons.notifications_active)
)
下面是一个前导的运行示例:
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppBar Title"),
leading: IconButton(
icon: Icon(Icons.notifications_active),
onPressed: () {
showAlert(context);
}
)
),
body: Center(
child: Text("Hello World.")
),
);
}
void showAlert(BuildContext context) {
showDialog(
context: context,
builder: (context) => AlertDialog(
content: Text("Hi"),
));
}
}
另外一个示例:
参考代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppBar Title"),
leading: MyVolumeButton()
),
body: Center(
child: Text("Hello World.")
),
);
}
}
class MyVolumeButton extends StatefulWidget {
MyVolumeButton({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() {
return MyVolumeButtonState();
}
}
class MyVolumeButtonState extends State<MyVolumeButton> {
bool volumeOn = true;
@override
Widget build(BuildContext context) {
return IconButton(
icon: this.volumeOn? Icon(Icons.volume_up):Icon(Icons.volume_mute),
onPressed: () {
// Set new State
setState(() => this.volumeOn = !this.volumeOn);
}
);
}
}
3. automaticallyImplyLeading
属性使用格式:
bool automaticallyImplyLeading: true
automaticImplyLeading
是AppBar的可选属性,其默认值为true
。如果没有在前导区域中放置任何窗口小部件,则可能会根据上下文自动在其中放置适当的窗口小部件。
情况1:如果满足以下条件,则IconButton
将自动添加到AppBar
的开头区域,以支持抽屉打开:
- AppBar的前导区域为空。
AppBar.automaticallyImplyLeading:true
。- AppBar放置在Scaffold中。
- Scaffold包含一个抽屉(指定了
Scaffold.drawer
)。
显示效果如下所示:
情况2:如果满足以下条件,则IconButton-“返回”将自动添加到AppBar的开头区域,用于返回到上一个屏幕:
- AppBar的前导区域为空。
AppBar. automaticallyImplyLeading:true
AppBar.drawer:null
- 从上一个屏幕跳至当前屏幕。
显示效果如下所示:
示例代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
// AppBar with automaticallyImplyLeading = "true" (Default)
appBar: AppBar(
title: Text("AppBar Title"),
automaticallyImplyLeading: true
),
body: Center(
child: Text("Hello World.")
),
drawer: Drawer(
child: ListView(
children: const <Widget> [
DrawerHeader(
decoration: BoxDecoration(
color: Colors.green,
),
child: Text(
'My Drawer',
style: TextStyle(
color: Colors.green,
fontSize: 24,
),
),
),
ListTile(
title: Text('Gallery'),
),
ListTile(
title: Text('Slideshow'),
),
],
),
),
);
}
}
5. actions属性
actions
属性可将动作添加到AppBar的工具栏中。通常,IconButton
将用于每个常见操作。但是对于不太常见的操作,应该考虑使用PopupMenuButton
。
List<Widget> actions
向AppBar的工具栏添加操作的示例。
示例代码:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("AppBar Title"),
actions: <Widget> [
IconButton(
icon: Icon(Icons.file_upload),
onPressed: () => {
print("Click on upload button")
},
),
IconButton(
icon: Icon(Icons.settings),
onPressed: () => {
print("Click on settings button")
}
),
PopupMenuButton(
icon: Icon(Icons.share),
itemBuilder: (context) => [
PopupMenuItem(
value: 1,
child: Text("Facebook"),
),
PopupMenuItem(
value: 2,
child: Text("Instagram"),
),
],
)
]
),
body: Center(
child: Text(
'Flutter AppBar Tutorial',
)
),
);
}
}
注意:动作的高度受工具栏的高度限制,但是可以通过使用
toolbarHeight
属性设置工具栏的高度。
5. 底部区域
AppBar的底部区域通常用于包含TabBar
。
PreferredSizeWidget bottom;
底部区域的示例代码如下:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title of Application',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
Tab(icon: Icon(Icons.directions_bike)),
],
),
title: Text('Flutter AppBar Example'),
),
body: TabBarView (
children: [
Center(child: Text("Car")),
Center(child: Text("Transit")),
Center(child: Text("Bike"))
],
),
)
);
}
}