This repository has been archived by the owner on Feb 22, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Material 3 support for BottomAppBar (#106525)
- Loading branch information
1 parent
3894a06
commit 0e98194
Showing
9 changed files
with
619 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// 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. | ||
|
||
import 'template.dart'; | ||
|
||
class BottomAppBarTemplate extends TokenTemplate { | ||
const BottomAppBarTemplate(super.blockName, super.fileName, super.tokens); | ||
|
||
@override | ||
String generate() => ''' | ||
// Generated version ${tokens["version"]} | ||
class _${blockName}DefaultsM3 extends BottomAppBarTheme { | ||
const _${blockName}DefaultsM3(this.context) | ||
: super( | ||
elevation: ${elevation('md.comp.bottom-app-bar.container')}, | ||
height: ${tokens['md.comp.bottom-app-bar.container.height']}, | ||
); | ||
final BuildContext context; | ||
@override | ||
Color? get color => ${componentColor('md.comp.bottom-app-bar.container')}; | ||
@override | ||
Color? get surfaceTintColor => ${componentColor('md.comp.bottom-app-bar.container.surface-tint-layer')}; | ||
@override | ||
NotchedShape? get shape => const AutomaticNotchedShape(${shape('md.comp.bottom-app-bar.container')}); | ||
} | ||
'''; | ||
} |
193 changes: 193 additions & 0 deletions
193
examples/api/lib/material/bottom_app_bar/bottom_app_bar.2.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
// 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: () {}, | ||
), | ||
], | ||
), | ||
), | ||
); | ||
} | ||
} |
Oops, something went wrong.