任何具有PreferredSize的widget都可以出现在AppBar的底部。
通常,AppBar的底部widget是TabBar,但是可以使用具有PreferredSize的任何widget。在这个应用程序中,应用程序栏的底部widget是一个TabPageSelector,用于显示应用程序的TabBarView中所选页面的相对位置。 可以通过工具栏部中的箭头按钮,选择上一页或下一页。
通过flutter create命令创建一个新项目,并用下面的代码替换lib/main.dart的内容来尝试运行一下。
// Copyright 2017 The Chromium Authors. All rights reserved.// Use of this source code is governed by a BSD-style license that can be// found in the LICENSE file.import 'package:flutter/material.dart';class AppBarBottomSample extends StatefulWidget {@override_AppBarBottomSampleState createState() => new _AppBarBottomSampleState();}class _AppBarBottomSampleState extends State<AppBarBottomSample> with SingleTickerProviderStateMixin {TabController _tabController;@overridevoid initState() {super.initState();_tabController = new TabController(vsync: this, length: choices.length);}@overridevoid dispose() {_tabController.dispose();super.dispose();}void _nextPage(int delta) {final int newIndex = _tabController.index + delta;if (newIndex < 0 || newIndex >= _tabController.length)return;_tabController.animateTo(newIndex);}@overrideWidget build(BuildContext context) {return new MaterialApp(home: new Scaffold(appBar: new AppBar(title: const Text('AppBar Bottom Widget'),leading: new IconButton(tooltip: 'Previous choice',icon: const Icon(Icons.arrow_back),onPressed: () { _nextPage(-1); },),actions: <Widget>[new IconButton(icon: const Icon(Icons.arrow_forward),tooltip: 'Next choice',onPressed: () { _nextPage(1); },),],bottom: new PreferredSize(preferredSize: const Size.fromHeight(48.0),child: new Theme(data: Theme.of(context).copyWith(accentColor: Colors.white),child: new Container(height: 48.0,alignment: Alignment.center,child: new TabPageSelector(controller: _tabController),),),),),body: new TabBarView(controller: _tabController,children: choices.map((Choice choice) {return new Padding(padding: const EdgeInsets.all(16.0),child: new ChoiceCard(choice: choice),);}).toList(),),),);}}class Choice {const Choice({ this.title, this.icon });final String title;final IconData icon;}const List<Choice> choices = const <Choice>[const Choice(title: 'CAR', icon: Icons.directions_car),const Choice(title: 'BICYCLE', icon: Icons.directions_bike),const Choice(title: 'BOAT', icon: Icons.directions_boat),const Choice(title: 'BUS', icon: Icons.directions_bus),const Choice(title: 'TRAIN', icon: Icons.directions_railway),const Choice(title: 'WALK', icon: Icons.directions_walk),];class ChoiceCard extends StatelessWidget {const ChoiceCard({ Key key, this.choice }) : super(key: key);final Choice choice;@overrideWidget build(BuildContext context) {final TextStyle textStyle = Theme.of(context).textTheme.display1;return new Card(color: Colors.white,child: new Center(child: new Column(mainAxisSize: MainAxisSize.min,crossAxisAlignment: CrossAxisAlignment.center,children: <Widget>[new Icon(choice.icon, size: 128.0, color: textStyle.color),new Text(choice.title, style: textStyle),],),),);}}void main() {runApp(new AppBarBottomSample());}
也可以看看:
- Material Design规范的Components-Tabs部分。
- 本示例源代码 examples/catalog/lib/app_bar_bottom.dart.
