Search code examples
flutterflutter-navigationflutter-bottomnavigation

Flutter Navigator v2.0 how to pop a child nested route


I've been trying flutter new declarative Navigator v2.0, following this johnpryan example, I've decide to change FlatButton pop() in the BookDetailsScreen:

class BookDetailsScreen extends StatelessWidget {
  @override
 Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
       children: [
            FlatButton(
              onPressed: () {
               Navigator.of(context).pop();
              },
              child: Text('Back'),
              ),
          ],
}

To the parent router AppBar() in the _AppShellState:

class _AppShellState extends State<AppShell> {
  InnerRouterDelegate _routerDelegate;
  ChildBackButtonDispatcher _backButtonDispatcher;

  @override
  Widget build(BuildContext context) {
    var appState = widget.appState;

    _backButtonDispatcher.takePriority();
    return Scaffold(
      appBar: appState.selectedBook != null
          ? AppBar(
              leading: IconButton(
                icon: Icon(Icons.arrow_back),
                onPressed: () => _routerDelegate.popRoute(),
              ),
              actions: [
                IconButton(
                  icon: Icon(Icons.more_vert),
                  onPressed: () => null,
                )
              ],
            )
          : AppBar(),
      body: Router(
        routerDelegate: _routerDelegate,
        backButtonDispatcher: _backButtonDispatcher,
      ),

Fullcode

My question is, I'm using _routerDelegate.popRoute() it's working, but I not sure if it is right way to do it?

PS: If someone have a more complex example using Navigator v2.0, I'm new to Flutter and need to know best practices to how separate and organize my code, how to add more routes for instance an Edit and login screen? working with more objects like users, books, authors and etc...


Solution

  • I have a tweak to show the back button, kinda naturally, when the BookDetailsScreen is presented.

    1. In the _AppShellState class
     @override
      Widget build(BuildContext context) {
        ... 
    
        return Scaffold(
          // <- Comment out this appBar
          // appBar: AppBar(
          //   leading: appState.selectedBook != null
          //       ? IconButton(
          //           icon: Icon(Icons.arrow_back),
          //           onPressed: () => _routerDelegate.popRoute(),
          //         )
          //       : null,
          // ),
          ...
          // Keep the rest part the same
          
        );
      }
    
    1. Add the appBar property into Screens Scaffold in the build method, like this below. Have the appBar on both BooksListScreen and BookDetailsScreen,
    class BooksListScreen extends StatelessWidget {
      ...
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(), // <- This is the key
          ...
        );
      }
    }
    

    Hope this makes sense.