diff --git a/examples/api/lib/material/navigation_bar/navigation_bar.2.dart b/examples/api/lib/material/navigation_bar/navigation_bar.2.dart index b0056c37bc9..feeef35796d 100644 --- a/examples/api/lib/material/navigation_bar/navigation_bar.2.dart +++ b/examples/api/lib/material/navigation_bar/navigation_bar.2.dart @@ -32,33 +32,47 @@ class _HomeState extends State with TickerProviderStateMixin { int selectedIndex = 0; AnimationController buildFaderController() { - final AnimationController controller = - AnimationController(vsync: this, duration: const Duration(milliseconds: 200)); - controller.addStatusListener((AnimationStatus status) { - if (status == AnimationStatus.dismissed) { - setState(() {}); // Rebuild unselected destinations offstage. - } - }); + final AnimationController controller = AnimationController( + vsync: this, + duration: const Duration(milliseconds: 300), + ); + controller.addStatusListener( + (AnimationStatus status) { + if (status == AnimationStatus.dismissed) { + setState(() {}); // Rebuild unselected destinations offstage. + } + }, + ); return controller; } @override void initState() { super.initState(); - navigatorKeys = - List>.generate(allDestinations.length, (int index) => GlobalKey()).toList(); - destinationFaders = - List.generate(allDestinations.length, (int index) => buildFaderController()).toList(); + + navigatorKeys = List>.generate( + allDestinations.length, + (int index) => GlobalKey(), + ).toList(); + + destinationFaders = List.generate( + allDestinations.length, + (int index) => buildFaderController(), + ).toList(); destinationFaders[selectedIndex].value = 1.0; - destinationViews = allDestinations.map((Destination destination) { - return FadeTransition( - opacity: destinationFaders[destination.index].drive(CurveTween(curve: Curves.fastOutSlowIn)), - child: DestinationView( - destination: destination, - navigatorKey: navigatorKeys[destination.index], - ), - ); - }).toList(); + + final CurveTween tween = CurveTween(curve: Curves.fastOutSlowIn); + destinationViews = allDestinations.map( + (Destination destination) { + return FadeTransition( + opacity: destinationFaders[destination.index].drive(tween), + child: DestinationView( + destination: destination, + navigatorKey: navigatorKeys[destination.index], + ), + ); + }, + ).toList(); } @override @@ -81,20 +95,22 @@ class _HomeState extends State with TickerProviderStateMixin { top: false, child: Stack( fit: StackFit.expand, - children: allDestinations.map((Destination destination) { - final int index = destination.index; - final Widget view = destinationViews[index]; - if (index == selectedIndex) { - destinationFaders[index].forward(); - return Offstage(offstage: false, child: view); - } else { - destinationFaders[index].reverse(); - if (destinationFaders[index].isAnimating) { - return IgnorePointer(child: view); + children: allDestinations.map( + (Destination destination) { + final int index = destination.index; + final Widget view = destinationViews[index]; + if (index == selectedIndex) { + destinationFaders[index].forward(); + return Offstage(offstage: false, child: view); + } else { + destinationFaders[index].reverse(); + if (destinationFaders[index].isAnimating) { + return IgnorePointer(child: view); + } + return Offstage(child: view); } - return Offstage(child: view); - } - }).toList(), + }, + ).toList(), ), ), bottomNavigationBar: NavigationBar( @@ -104,12 +120,14 @@ class _HomeState extends State with TickerProviderStateMixin { selectedIndex = index; }); }, - destinations: allDestinations.map((Destination destination) { - return NavigationDestination( - icon: Icon(destination.icon, color: destination.color), - label: destination.title, - ); - }).toList(), + destinations: allDestinations.map( + (Destination destination) { + return NavigationDestination( + icon: Icon(destination.icon, color: destination.color), + label: destination.title, + ); + }, + ).toList(), ), ), ); @@ -148,6 +166,7 @@ class RootPage extends StatelessWidget { final TextStyle headlineSmall = Theme.of(context).textTheme.headlineSmall!; final ButtonStyle buttonStyle = ElevatedButton.styleFrom( backgroundColor: destination.color, + foregroundColor: Colors.white, visualDensity: VisualDensity.comfortable, padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), textStyle: headlineSmall, @@ -157,6 +176,7 @@ class RootPage extends StatelessWidget { appBar: AppBar( title: Text('${destination.title} RootPage - /'), backgroundColor: destination.color, + foregroundColor: Colors.white, ), backgroundColor: destination.color[50], body: Center( @@ -236,15 +256,23 @@ class ListPage extends StatelessWidget { @override Widget build(BuildContext context) { const int itemCount = 50; + final ColorScheme colorScheme = Theme.of(context).colorScheme; final ButtonStyle buttonStyle = OutlinedButton.styleFrom( + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8), + side: BorderSide( + color: colorScheme.onSurface.withOpacity(0.12), + ), + ), foregroundColor: destination.color, - fixedSize: const Size.fromHeight(128), + fixedSize: const Size.fromHeight(64), textStyle: Theme.of(context).textTheme.headlineSmall, ); return Scaffold( appBar: AppBar( title: Text('${destination.title} ListPage - /list'), backgroundColor: destination.color, + foregroundColor: Colors.white, ), backgroundColor: destination.color[50], body: SizedBox.expand( @@ -256,7 +284,11 @@ class ListPage extends StatelessWidget { child: OutlinedButton( style: buttonStyle.copyWith( backgroundColor: MaterialStatePropertyAll( - Color.lerp(destination.color[100], Colors.white, index / itemCount)!, + Color.lerp( + destination.color[100], + Colors.white, + index / itemCount + )!, ), ), onPressed: () { @@ -303,6 +335,7 @@ class _TextPageState extends State { appBar: AppBar( title: Text('${widget.destination.title} TextPage - /list/text'), backgroundColor: widget.destination.color, + foregroundColor: Colors.white, ), backgroundColor: widget.destination.color[50], body: Container( diff --git a/packages/flutter/lib/src/material/navigation_bar.dart b/packages/flutter/lib/src/material/navigation_bar.dart index 039baaf2247..44afd3c5c72 100644 --- a/packages/flutter/lib/src/material/navigation_bar.dart +++ b/packages/flutter/lib/src/material/navigation_bar.dart @@ -62,12 +62,18 @@ const double _kIndicatorWidth = 64; /// {@end-tool} /// /// {@tool dartpad} -/// This example shows a [NavigationBar] as it is used within a [Scaffold] -/// widget when there are nested navigators that provide local navigation. The -/// [NavigationBar] has four [NavigationDestination] widgets with different -/// color schemes. The [onDestinationSelected] callback changes the selected -/// item's index and displays a corresponding page with its own local navigator -/// in the body of a [Scaffold]. +/// This example shows a [NavigationBar] within a main [Scaffold] +/// widget that's used to control the visibility of destination pages. +/// Each destination has its own scaffold and a nested navigator that +/// provides local navigation. The example's [NavigationBar] has four +/// [NavigationDestination] widgets with different color schemes. Its +/// [onDestinationSelected] callback changes the selected +/// destination's index and displays a corresponding page with its own +/// local navigator and scaffold - all within the body of the main +/// scaffold. The destination pages are organized in a [Stack] and +/// switching destinations fades out the current page and +/// fades in the new one. Destinations that aren't visible or animating +/// are kept [Offstage]. /// /// ** See code in examples/api/lib/material/navigation_bar/navigation_bar.2.dart ** /// {@end-tool}