| // 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; |
| |
| @override |
| void initState() { |
| super.initState(); |
| _tabController = new TabController(vsync: this, length: choices.length); |
| } |
| |
| @override |
| void 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); |
| } |
| |
| @override |
| Widget 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 = <Choice>[ |
| Choice(title: 'CAR', icon: Icons.directions_car), |
| Choice(title: 'BICYCLE', icon: Icons.directions_bike), |
| Choice(title: 'BOAT', icon: Icons.directions_boat), |
| Choice(title: 'BUS', icon: Icons.directions_bus), |
| Choice(title: 'TRAIN', icon: Icons.directions_railway), |
| Choice(title: 'WALK', icon: Icons.directions_walk), |
| ]; |
| |
| class ChoiceCard extends StatelessWidget { |
| const ChoiceCard({ Key key, this.choice }) : super(key: key); |
| |
| final Choice choice; |
| |
| @override |
| Widget 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()); |
| } |
| |
| /* |
| Sample Catalog |
| |
| Title: AppBar with a custom bottom widget. |
| |
| Summary: An AppBar that includes a bottom widget. Any widget |
| with a PreferredSize can appear at the bottom of an AppBar. |
| |
| Summary: Any widget with a PreferredSize can appear at the bottom of an AppBar. |
| |
| Description: |
| Typically an AppBar's bottom widget is a TabBar however any widget with a |
| PreferredSize can be used. In this app, the app bar's bottom widget is a |
| TabPageSelector that displays the relative position of the selected page |
| in the app's TabBarView. The arrow buttons in the toolbar part of the app |
| bar and they select the previous or the next page. |
| |
| Classes: AppBar, PreferredSize, TabBarView, TabController |
| |
| Sample: AppBarBottomSample |
| |
| See also: |
| - The "Components-Tabs" section of the material design specification: |
| <https://material.io/go/design-tabs> |
| */ |