How to do nested navigation in Flutter

前端 未结 2 1655
孤城傲影
孤城傲影 2020-12-24 03:53

Does anyone have any recommendations for figuring out nested navigation in Flutter?

What I want is to keep a persistent BottomNavigationBar even when redirecting to

相关标签:
2条回答
  • 2020-12-24 04:34

    Here is the example code for persistent BottomNavigationBar as a starter:

    import 'package:flutter/material.dart';
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MainPage(),
        );
      }
    }
    
    class MainPage extends StatelessWidget {
      final navigatorKey = GlobalKey<NavigatorState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            children: <Widget>[
              Expanded(
                child: Navigator(
                  key: navigatorKey,
                  onGenerateRoute: (route) => MaterialPageRoute(
                        settings: route,
                        builder: (context) => PageOne(),
                      ),
                ),
              ),
              BottomNavigationBar(navigatorKey)
            ],
          ),
        );
      }
    }
    
    class BottomNavigationBar extends StatelessWidget {
      final GlobalKey<NavigatorState> navigatorKey;
    
      BottomNavigationBar(this.navigatorKey) : assert(navigatorKey != null);
    
      Future<void> push(Route route) {
        return navigatorKey.currentState.push(route);
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          color: Colors.blue,
          child: ButtonBar(
            alignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              RaisedButton(
                child: Text("PageOne"),
                onPressed: () {
                  push(MaterialPageRoute(builder: (context) => PageOne()));
                },
              ),
              RaisedButton(
                child: Text("PageTwo"),
                onPressed: () {
                  push(MaterialPageRoute(builder: (context) => PageTwo()));
                },
              )
            ],
          ),
        );
      }
    }
    
    class PageOne extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text("Page One"),
              RaisedButton(
                onPressed: (){
                  Navigator.of(context).pop();
                },
                child: Text("Pop"),
              ),
            ],
          ),
        );
      }
    }
    
    class PageTwo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text("Page Two"),
              RaisedButton(
                onPressed: (){
                  Navigator.of(context).pop();
                },
                child: Text("Pop"),
              ),
            ],
          ),
        );
      }
    }
    

    Here is how it the screen record

    0 讨论(0)
  • 2020-12-24 04:37

    Here is a simple example that even supports popping to the first screen with a tab bar.

    import 'package:flutter/material.dart';
    
    import '../bible/screen.dart';
    import '../library/screen.dart';
    import '../playlists/screen.dart';
    import '../search/screen.dart';
    import '../settings/screen.dart';
    
    class TabsScreen extends StatefulWidget {
      @override
      _TabsScreenState createState() => _TabsScreenState();
    }
    
    class _TabsScreenState extends State<TabsScreen> {
      int _currentIndex = 0;
    
      final _libraryScreen = GlobalKey<NavigatorState>();
      final _playlistScreen = GlobalKey<NavigatorState>();
      final _searchScreen = GlobalKey<NavigatorState>();
      final _bibleScreen = GlobalKey<NavigatorState>();
      final _settingsScreen = GlobalKey<NavigatorState>();
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: IndexedStack(
            index: _currentIndex,
            children: <Widget>[
              Navigator(
                key: _libraryScreen,
                onGenerateRoute: (route) => MaterialPageRoute(
                  settings: route,
                  builder: (context) => LibraryScreen(),
                ),
              ),
              Navigator(
                key: _playlistScreen,
                onGenerateRoute: (route) => MaterialPageRoute(
                  settings: route,
                  builder: (context) => PlaylistsScreen(),
                ),
              ),
              Navigator(
                key: _searchScreen,
                onGenerateRoute: (route) => MaterialPageRoute(
                  settings: route,
                  builder: (context) => SearchScreen(),
                ),
              ),
              Navigator(
                key: _bibleScreen,
                onGenerateRoute: (route) => MaterialPageRoute(
                  settings: route,
                  builder: (context) => BibleScreen(),
                ),
              ),
              Navigator(
                key: _settingsScreen,
                onGenerateRoute: (route) => MaterialPageRoute(
                  settings: route,
                  builder: (context) => SettingsScreen(),
                ),
              ),
            ],
          ),
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            currentIndex: _currentIndex,
            onTap: (val) => _onTap(val, context),
            backgroundColor: Theme.of(context).scaffoldBackgroundColor,
            items: [
              BottomNavigationBarItem(
                icon: Icon(Icons.library_books),
                title: Text('Library'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.list),
                title: Text('Playlists'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.search),
                title: Text('Search'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.import_contacts),
                title: Text('Bible'),
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.settings),
                title: Text('Settings'),
              ),
            ],
          ),
        );
      }
    
      void _onTap(int val, BuildContext context) {
        if (_currentIndex == val) {
          switch (val) {
            case 0:
              _libraryScreen.currentState.popUntil((route) => route.isFirst);
              break;
            case 1:
              _playlistScreen.currentState.popUntil((route) => route.isFirst);
              break;
            case 2:
              _searchScreen.currentState.popUntil((route) => route.isFirst);
              break;
            case 3:
              _bibleScreen.currentState.popUntil((route) => route.isFirst);
              break;
            case 4:
              _settingsScreen.currentState.popUntil((route) => route.isFirst);
              break;
            default:
          }
        } else {
          if (mounted) {
            setState(() {
              _currentIndex = val;
            });
          }
        }
      }
    }
    
    
    0 讨论(0)
提交回复
热议问题