| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Flutter code sample for BottomAppBar with Material 3 |
| |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/rendering.dart'; |
| |
| void main() { |
| runApp(const BottomAppBarDemo()); |
| } |
| |
| class BottomAppBarDemo extends StatefulWidget { |
| const BottomAppBarDemo({super.key}); |
| |
| @override |
| State createState() => _BottomAppBarDemoState(); |
| } |
| |
| class _BottomAppBarDemoState extends State<BottomAppBarDemo> { |
| static const List<Color> colors = <Color>[ |
| Colors.yellow, |
| Colors.orange, |
| Colors.pink, |
| Colors.purple, |
| Colors.cyan, |
| ]; |
| |
| static final List<Widget> items = List<Widget>.generate( |
| colors.length, |
| (int index) => Container(color: colors[index], height: 150.0), |
| ).reversed.toList(); |
| |
| late ScrollController _controller; |
| bool _showFab = true; |
| bool _isElevated = true; |
| bool _isVisible = true; |
| |
| FloatingActionButtonLocation get _fabLocation => _isVisible |
| ? FloatingActionButtonLocation.endContained |
| : FloatingActionButtonLocation.endFloat; |
| |
| void _listen() { |
| final ScrollDirection direction = _controller.position.userScrollDirection; |
| if (direction == ScrollDirection.forward) { |
| _show(); |
| } else if (direction == ScrollDirection.reverse) { |
| _hide(); |
| } |
| } |
| |
| void _show() { |
| if (!_isVisible) { |
| setState(() => _isVisible = true); |
| } |
| } |
| |
| void _hide() { |
| if (_isVisible) { |
| setState(() => _isVisible = false); |
| } |
| } |
| |
| void _onShowFabChanged(bool value) { |
| setState(() { |
| _showFab = value; |
| }); |
| } |
| |
| void _onElevatedChanged(bool value) { |
| setState(() { |
| _isElevated = value; |
| }); |
| } |
| |
| void _addNewItem() { |
| setState(() { |
| items.insert( |
| 0, |
| Container(color: colors[items.length % 5], height: 150.0), |
| ); |
| }); |
| } |
| |
| @override |
| void initState() { |
| super.initState(); |
| _controller = ScrollController(); |
| _controller.addListener(_listen); |
| } |
| |
| @override |
| void dispose() { |
| _controller.removeListener(_listen); |
| _controller.dispose(); |
| super.dispose(); |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| return MaterialApp( |
| theme: ThemeData(useMaterial3: true), |
| home: Scaffold( |
| appBar: AppBar( |
| title: const Text('Bottom App Bar Demo'), |
| ), |
| body: Column( |
| children: <Widget>[ |
| SwitchListTile( |
| title: const Text('Floating Action Button'), |
| value: _showFab, |
| onChanged: _onShowFabChanged, |
| ), |
| SwitchListTile( |
| title: const Text('Bottom App Bar Elevation'), |
| value: _isElevated, |
| onChanged: _onElevatedChanged, |
| ), |
| Expanded( |
| child: ListView( |
| controller: _controller, |
| children: items.toList(), |
| ), |
| ), |
| ], |
| ), |
| floatingActionButton: _showFab |
| ? FloatingActionButton( |
| onPressed: _addNewItem, |
| tooltip: 'Add New Item', |
| elevation: _isVisible ? 0.0 : null, |
| child: const Icon(Icons.add), |
| ) |
| : null, |
| floatingActionButtonLocation: _fabLocation, |
| bottomNavigationBar: _DemoBottomAppBar(isElevated: _isElevated, isVisible: _isVisible), |
| ), |
| ); |
| } |
| } |
| |
| class _DemoBottomAppBar extends StatelessWidget { |
| const _DemoBottomAppBar({ |
| required this.isElevated, |
| required this.isVisible, |
| }); |
| |
| final bool isElevated; |
| final bool isVisible; |
| |
| @override |
| Widget build(BuildContext context) { |
| return AnimatedContainer( |
| duration: const Duration(milliseconds: 200), |
| height: isVisible ? 80.0 : 0, |
| child: BottomAppBar( |
| elevation: isElevated ? null : 0.0, |
| child: Row( |
| children: <Widget>[ |
| IconButton( |
| tooltip: 'Open popup menu', |
| icon: const Icon(Icons.more_vert), |
| onPressed: () { |
| final SnackBar snackBar = SnackBar( |
| content: const Text('Yay! A SnackBar!'), |
| action: SnackBarAction( |
| label: 'Undo', |
| onPressed: () {}, |
| ), |
| ); |
| |
| // Find the ScaffoldMessenger in the widget tree |
| // and use it to show a SnackBar. |
| ScaffoldMessenger.of(context).showSnackBar(snackBar); |
| }, |
| ), |
| IconButton( |
| tooltip: 'Search', |
| icon: const Icon(Icons.search), |
| onPressed: () {}, |
| ), |
| IconButton( |
| tooltip: 'Favorite', |
| icon: const Icon(Icons.favorite), |
| onPressed: () {}, |
| ), |
| ], |
| ), |
| ), |
| ); |
| } |
| } |