| // 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. |
| |
| // Builds an adaptive navigation widget layout. When the screen width is less than |
| // 450, A [NavigationBar] will be displayed. Otherwise, a [NavigationRail] will be |
| // displayed on the left side, and also a button to open the [NavigationDrawer]. |
| // All of these navigation widgets are built from an identical list of data. |
| |
| import 'package:flutter/material.dart'; |
| |
| /// Flutter code sample for [NavigationDrawer]. |
| |
| void main() => runApp(const NavigationDrawerApp()); |
| |
| class ExampleDestination { |
| const ExampleDestination(this.label, this.icon, this.selectedIcon); |
| |
| final String label; |
| final Widget icon; |
| final Widget selectedIcon; |
| } |
| |
| const List<ExampleDestination> destinations = <ExampleDestination>[ |
| ExampleDestination('Messages', Icon(Icons.widgets_outlined), Icon(Icons.widgets)), |
| ExampleDestination('Profile', Icon(Icons.format_paint_outlined), Icon(Icons.format_paint)), |
| ExampleDestination('Settings', Icon(Icons.settings_outlined), Icon(Icons.settings)), |
| ]; |
| |
| class NavigationDrawerApp extends StatelessWidget { |
| const NavigationDrawerApp({super.key}); |
| |
| @override |
| Widget build(BuildContext context) { |
| return MaterialApp( |
| debugShowCheckedModeBanner: false, |
| theme: ThemeData(useMaterial3: true), |
| home: const NavigationDrawerExample(), |
| ); |
| } |
| } |
| |
| class NavigationDrawerExample extends StatefulWidget { |
| const NavigationDrawerExample({super.key}); |
| |
| @override |
| State<NavigationDrawerExample> createState() => _NavigationDrawerExampleState(); |
| } |
| |
| class _NavigationDrawerExampleState extends State<NavigationDrawerExample> { |
| final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>(); |
| |
| int screenIndex = 0; |
| late bool showNavigationDrawer; |
| |
| void handleScreenChanged(int selectedScreen) { |
| setState(() { |
| screenIndex = selectedScreen; |
| }); |
| } |
| |
| void openDrawer() { |
| scaffoldKey.currentState!.openEndDrawer(); |
| } |
| |
| Widget buildBottomBarScaffold() { |
| return Scaffold( |
| body: Center( |
| child: Column( |
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
| children: <Widget>[ |
| Text('Page Index = $screenIndex'), |
| ], |
| ), |
| ), |
| bottomNavigationBar: NavigationBar( |
| selectedIndex: screenIndex, |
| onDestinationSelected: (int index) { |
| setState(() { |
| screenIndex = index; |
| }); |
| }, |
| destinations: destinations.map( |
| (ExampleDestination destination) { |
| return NavigationDestination( |
| label: destination.label, |
| icon: destination.icon, |
| selectedIcon: destination.selectedIcon, |
| tooltip: destination.label, |
| ); |
| }, |
| ).toList(), |
| ), |
| ); |
| } |
| |
| Widget buildDrawerScaffold(BuildContext context) { |
| return Scaffold( |
| key: scaffoldKey, |
| body: SafeArea( |
| bottom: false, |
| top: false, |
| child: Row( |
| children: <Widget>[ |
| Padding( |
| padding: const EdgeInsets.symmetric(horizontal: 5), |
| child: NavigationRail( |
| minWidth: 50, |
| destinations: destinations.map( |
| (ExampleDestination destination) { |
| return NavigationRailDestination( |
| label: Text(destination.label), |
| icon: destination.icon, |
| selectedIcon: destination.selectedIcon, |
| ); |
| }, |
| ).toList(), |
| selectedIndex: screenIndex, |
| useIndicator: true, |
| onDestinationSelected: (int index) { |
| setState(() { |
| screenIndex = index; |
| }); |
| }, |
| ), |
| ), |
| const VerticalDivider(thickness: 1, width: 1), |
| Expanded( |
| child: Column( |
| mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
| children: <Widget>[ |
| Text('Page Index = $screenIndex'), |
| ElevatedButton( |
| onPressed: openDrawer, |
| child: const Text('Open Drawer'), |
| ), |
| ], |
| ), |
| ), |
| ], |
| ), |
| ), |
| endDrawer: NavigationDrawer( |
| onDestinationSelected: handleScreenChanged, |
| selectedIndex: screenIndex, |
| children: <Widget>[ |
| Padding( |
| padding: const EdgeInsets.fromLTRB(28, 16, 16, 10), |
| child: Text( |
| 'Header', |
| style: Theme.of(context).textTheme.titleSmall, |
| ), |
| ), |
| ...destinations.map( |
| (ExampleDestination destination) { |
| return NavigationDrawerDestination( |
| label: Text(destination.label), |
| icon: destination.icon, |
| selectedIcon: destination.selectedIcon, |
| ); |
| }, |
| ), |
| const Padding( |
| padding: EdgeInsets.fromLTRB(28, 16, 28, 10), |
| child: Divider(), |
| ), |
| ], |
| ), |
| ); |
| } |
| |
| @override |
| void didChangeDependencies() { |
| super.didChangeDependencies(); |
| showNavigationDrawer = MediaQuery.of(context).size.width >= 450; |
| } |
| |
| @override |
| Widget build(BuildContext context) { |
| return showNavigationDrawer ? buildDrawerScaffold(context) : buildBottomBarScaffold(); |
| } |
| } |