title: How to know pop event happened inside Nested Widget in Flutter
body: <p>I am currently building app where I need to use Nested Routing keeping one screen same and routing on different one. I want to when that second route is popped so that I can change value of expanded to fill whole screen. <a href="https://gist.github.com/ratnadeep007/00e0237f71a5f8a3d645129a97cebde0" rel="nofollow noreferrer">Gist in Github</a>.
  Here is code sample:</p>
  
  <pre class="lang-dart prettyprint-override"><code>import 'package:flutter/material.dart';
  
  void main() =&gt; runApp(MyApp());
  
  class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(body: MyHomePage()),
      );
    }
  }
  
  class MyHomePage extends StatefulWidget {
    MyHomePage({Key key}) : super(key: key);
  
    @override
    _MyHomePageState createState() =&gt; _MyHomePageState();
  }
  
  class _MyHomePageState extends State&lt;MyHomePage&gt; with RouteAware {
    bool rightPanelIsShown;
    Widget child;
    final GlobalKey&lt;NavigatorState&gt; navigatorKey = GlobalKey();
    final RouteObserver&lt;PageRoute&gt; _routeObserver = RouteObserver&lt;PageRoute&gt;();
  
    @override
    void initState() {
      super.initState();
      setState(() {
        rightPanelIsShown = false;
        child = Container();
      });
    }
  
    @override
    void didChangeDependencies() {
      super.didChangeDependencies();
      _routeObserver.subscribe(this, ModalRoute.of(context));
      setState(() {
        child = Container();
      });
    }
  
    @override
    void didPop() {
      super.didPop();
      print('popped');
      setState(() {
        rightPanelIsShown = false;
      });
    }
  
    @override
    void dispose() {
      print("dis");
      _routeObserver.unsubscribe(this);
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      return Container(
        color: Colors.white,
        child: Row(
          children: &lt;Widget&gt;[
            Expanded(
              flex: 1,
              child: Center(
                child: FlatButton(
                  color: Colors.blue,
                  onPressed: () =&gt; setState(() {
                    rightPanelIsShown = !rightPanelIsShown;
                    child = Page1();
                  }),
                  child: Text(
                    'Open Right Panel',
                    style: TextStyle(color: Colors.white, fontSize: 25.0),
                  ),
                ),
              ),
            ),
            rightPanelIsShown
                ? Expanded(
                    flex: 1,
                    child: Navigator(
                      onGenerateRoute: (route) =&gt; MaterialPageRoute(
                        builder: (context) =&gt; child,
                      ),
                    ),
                  )
                : Container(),
          ],
        ),
      );
    }
  }
  
  class Page1 extends StatelessWidget {
    const Page1({Key key}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return Container(
        child: Column(
          children: &lt;Widget&gt;[
            Text(
              'Page1',
              style: TextStyle(
                fontSize: 30.0,
              ),
            ),
            _buildGoToButton(context),
            _buildBackbutton(context)
          ],
        ),
      );
    }
  
    FlatButton _buildGoToButton(BuildContext context) {
      return FlatButton(
        color: Colors.green,
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (_) =&gt; Page2(),
            ),
          );
        },
        child: Text(
          'Go To Page 2',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  
    FlatButton _buildBackbutton(BuildContext context) {
      return FlatButton(
        color: Colors.red,
        onPressed: () {
          Navigator.pop(context);
        },
        child: Text(
          'Close',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  }
  
  class Page2 extends StatelessWidget {
    const Page2({Key key}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return Container(
        child: Column(
          children: &lt;Widget&gt;[
            Text(
              'Page2',
              style: TextStyle(
                fontSize: 30.0,
              ),
            ),
            _buildBackButton(context)
          ],
        ),
      );
    }
  
    FlatButton _buildBackButton(BuildContext context) {
      return FlatButton(
        color: Colors.red,
        onPressed: () {
          Navigator.pop(context);
        },
        child: Text(
          'Close',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  }
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/JlWio.gif" rel="nofollow noreferrer">Screencast of built upto</a></p>
  
  <p>When click on close on right panel Page1 it should also change state of parent.
  Thanks,</p>
  
  <h2>Update</h2>
  
  <p>Working with help of João Soares</p>
  
  <pre class="lang-dart prettyprint-override"><code>import 'package:flutter/material.dart';
  
  void main() =&gt; runApp(MyApp());
  
  class MyApp extends StatelessWidget {
    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: Scaffold(body: MyHomePage()),
      );
    }
  }
  
  class MyHomePage extends StatefulWidget {
    MyHomePage({Key key}) : super(key: key);
  
    @override
    _MyHomePageState createState() =&gt; _MyHomePageState();
  }
  
  class _MyHomePageState extends State&lt;MyHomePage&gt; with RouteAware {
    bool rightPanelIsShown;
    Widget child;
    final GlobalKey&lt;NavigatorState&gt; navigatorKey = GlobalKey();
    final RouteObserver&lt;PageRoute&gt; _routeObserver = RouteObserver&lt;PageRoute&gt;();
  
    @override
    void initState() {
      super.initState();
      setState(() {
        rightPanelIsShown = false;
        child = Container();
      });
    }
  
    @override
    void didChangeDependencies() {
      super.didChangeDependencies();
      _routeObserver.subscribe(this, ModalRoute.of(context));
      setState(() {
        child = Container();
      });
    }
  
    @override
    void didPop() {
      super.didPop();
      print('popped');
      setState(() {
        rightPanelIsShown = false;
      });
    }
  
    @override
    void dispose() {
      print("dis");
      _routeObserver.unsubscribe(this);
      super.dispose();
    }
  
    @override
    Widget build(BuildContext context) {
      return Container(
        color: Colors.white,
        child: Row(
          children: &lt;Widget&gt;[
            Expanded(
              flex: 1,
              child: Center(
                child: Column(
                  children: &lt;Widget&gt;[
                    FlatButton(
                      color: Colors.blue,
                      onPressed: () =&gt; setState(() {
                        rightPanelIsShown = !rightPanelIsShown;
                        child = Page1(
                          callback: onPop,
                        );
                      }),
                      child: Text(
                        'Open Right Panel 1',
                        style: TextStyle(color: Colors.white, fontSize: 25.0),
                      ),
                    ),
                    FlatButton(
                      color: Colors.blue,
                      onPressed: () =&gt; setState(() {
                        rightPanelIsShown = !rightPanelIsShown;
                        child = Page3(
                          callback: onPop,
                        );
                      }),
                      child: Text(
                        'Open Right Panel 2',
                        style: TextStyle(color: Colors.white, fontSize: 25.0),
                      ),
                    ),
                  ],
                ),
              ),
            ),
            rightPanelIsShown
                ? Expanded(
                    flex: 1,
                    child: PanelView(
                      child: child,
                    ),
                  )
                : Container(),
          ],
        ),
      );
    }
  
    onPop(value) {
      print("popped");
      setState(() {
        rightPanelIsShown = false;
      });
    }
  }
  
  class PanelView extends StatefulWidget {
    final Widget child;
  
    PanelView({Key key, this.child}) : super(key: key);
  
    @override
    _PanelViewState createState() =&gt; _PanelViewState();
  }
  
  class _PanelViewState extends State&lt;PanelView&gt; {
    @override
    Widget build(BuildContext context) {
      return Navigator(
        onGenerateRoute: (route) {
          return MaterialPageRoute(builder: (context) {
            return Container(
              child: widget.child,
            );
          });
        },
      );
    }
  }
  
  class Page1 extends StatelessWidget {
    final Function callback;
    const Page1({Key key, this.callback}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return Container(
        child: Column(
          children: &lt;Widget&gt;[
            Text(
              'Page1',
              style: TextStyle(
                fontSize: 30.0,
              ),
            ),
            _buildGoToButton(context),
            _buildBackbutton(context)
          ],
        ),
      );
    }
  
    FlatButton _buildGoToButton(BuildContext context) {
      return FlatButton(
        color: Colors.green,
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (_) =&gt; Page2(),
            ),
          );
        },
        child: Text(
          'Go To Page 2',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  
    FlatButton _buildBackbutton(BuildContext context) {
      return FlatButton(
        color: Colors.red,
        onPressed: () {
          callback('hello');
          Navigator.of(context).pop();
        },
        child: Text(
          'Close',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  }
  
  class Page2 extends StatelessWidget {
    const Page2({Key key}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return Container(
        child: Column(
          children: &lt;Widget&gt;[
            Text(
              'Page2',
              style: TextStyle(
                fontSize: 30.0,
              ),
            ),
            _buildBakButton(context)
          ],
        ),
      );
    }
  
    FlatButton _buildBakButton(BuildContext context) {
      return FlatButton(
        color: Colors.red,
        onPressed: () {
          Navigator.pop(context);
        },
        child: Text(
          'Close',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  }
  
  class Page3 extends StatelessWidget {
    final Function callback;
    const Page3({Key key, this.callback}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return Container(
        child: Column(
          children: &lt;Widget&gt;[
            Text(
              'Page2',
              style: TextStyle(
                fontSize: 30.0,
              ),
            ),
            _buildBakButton(context)
          ],
        ),
      );
    }
  
    FlatButton _buildBakButton(BuildContext context) {
      return FlatButton(
        color: Colors.red,
        onPressed: () {
          callback('page3');
          Navigator.pop(context);
        },
        child: Text(
          'Close',
          style: TextStyle(fontSize: 21.0),
        ),
      );
    }
  }
  </code></pre>
  
  <p>If there is better solution where I don't have to pass callback to every child widget of PanelView like if have 2 buttons in left panel and it determines which widget will be shown in right panel where button child determines child widget setting it in state.</p>