diff --git a/examples/api/lib/material/navigation_bar/navigation_bar.dart b/examples/api/lib/material/navigation_bar/navigation_bar.dart new file mode 100644 index 00000000000..98651df6731 --- /dev/null +++ b/examples/api/lib/material/navigation_bar/navigation_bar.dart @@ -0,0 +1,77 @@ +// 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 NavigationBar + +import 'package:flutter/material.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return const MaterialApp(home: NavigationExample()); + } +} + +class NavigationExample extends StatefulWidget { + const NavigationExample({Key? key}) : super(key: key); + + @override + State createState() => _NavigationExampleState(); +} + +class _NavigationExampleState extends State { + int currentPageIndex = 0; + + @override + Widget build(BuildContext context) { + return Scaffold( + bottomNavigationBar: NavigationBar( + onDestinationSelected: (int index) { + setState(() { + currentPageIndex = index; + }); + }, + selectedIndex: currentPageIndex, + destinations: const [ + NavigationDestination( + icon: Icon(Icons.explore), + label: 'Explore', + ), + NavigationDestination( + icon: Icon(Icons.commute), + label: 'Commute', + ), + NavigationDestination( + selectedIcon: Icon(Icons.bookmark), + icon: Icon(Icons.bookmark_border), + label: 'Saved', + ), + ], + ), + body: [ + Container( + color: Colors.red, + alignment: Alignment.center, + child: const Text('Page 1'), + ), + Container( + color: Colors.green, + alignment: Alignment.center, + child: const Text('Page 2'), + ), + Container( + color: Colors.blue, + alignment: Alignment.center, + child: const Text('Page 3'), + ), + ][currentPageIndex], + ); + } +} diff --git a/examples/api/test/material/navigation_bar/navigation_bar_test.dart b/examples/api/test/material/navigation_bar/navigation_bar_test.dart new file mode 100644 index 00000000000..cad8ee5d53a --- /dev/null +++ b/examples/api/test/material/navigation_bar/navigation_bar_test.dart @@ -0,0 +1,37 @@ +// 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 'package:flutter/material.dart'; +import 'package:flutter_api_samples/material/navigation_bar/navigation_bar.dart' + as example; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Navigation bar updates destination on tap', + (WidgetTester tester) async { + await tester.pumpWidget( + const example.MyApp(), + ); + final NavigationBar navigationBarWidget = + tester.firstWidget(find.byType(NavigationBar)); + + /// NavigationDestinations must be rendered + expect(find.text('Explore'), findsOneWidget); + expect(find.text('Commute'), findsOneWidget); + expect(find.text('Saved'), findsOneWidget); + + /// initial index must be zero + expect(navigationBarWidget.selectedIndex, 0); + + /// switch to second tab + await tester.tap(find.text('Commute')); + await tester.pumpAndSettle(); + expect(find.text('Page 2'), findsOneWidget); + + /// switch to third tab + await tester.tap(find.text('Saved')); + await tester.pumpAndSettle(); + expect(find.text('Page 3'), findsOneWidget); + }); +} diff --git a/packages/flutter/lib/src/material/navigation_bar.dart b/packages/flutter/lib/src/material/navigation_bar.dart index b299ef66979..47dd01eb529 100644 --- a/packages/flutter/lib/src/material/navigation_bar.dart +++ b/packages/flutter/lib/src/material/navigation_bar.dart @@ -33,47 +33,19 @@ import 'tooltip.dart'; /// This widget holds a collection of destinations (usually /// [NavigationDestination]s). /// -/// Usage: -/// ```dart -/// Scaffold( -/// bottomNavigationBar: NavigationBar( -/// onDestinationSelected: (int index) { -/// setState(() { _currentPageIndex = index; }), -/// }, -/// selectedIndex: _currentPageIndex, -/// destinations: [ -/// NavigationDestination( -/// icon: Icon(Icons.explore), -/// label: 'Explore', -/// ), -/// NavigationDestination( -/// icon: Icon(Icons.commute), -/// label: 'Commute', -/// ), -/// NavigationDestination( -/// selectedIcon: Icon(Icons.bookmark), -/// icon: Icon(Icons.bookmark_border), -/// label: 'Saved', -/// ), -/// ], -/// ), -/// ), -/// ``` -/// /// {@tool dartpad} -/// This example has a [NavigationBar] where each destination has its -/// own Navigator, Scaffold, and Appbar. That means that each -/// destination has an independent route history and (app bar) back -/// button. A [Stack] is used to display one destination at a time and -/// destination changes are handled by cross fade transitions. Destinations -/// that have been completely faded out are [Offstage]. +/// This example shows a [NavigationBar] as it is used within a [Scaffold] +/// widget. The [NavigationBar] has three [NavigationDestination] widgets +/// and the [selectedIndex] is set to index 0. The `onDestinationSelected` callback +/// changes the selected item's index and displays a corresponding widget in the body of the [Scaffold]. /// -/// One can see that the appearance of each destination's dialogs, bottom sheet, -/// list scrolling state, and text field state, persist when another destination -/// is selected. -/// -/// ** See code in examples/api/lib/material/navigation_bar/navigation_bar.0.dart ** +/// ** See code in examples/api/lib/material/navigation_bar/navigation_bar.dart ** /// {@end-tool} +/// See also: +/// +/// * [NavigationDestination] +/// * [BottomNavigationBar] +/// * class NavigationBar extends StatelessWidget { /// Creates a Material 3 Navigation Bar component. ///