addLocalHistoryEntry method

void addLocalHistoryEntry (
  1. LocalHistoryEntry entry
)
inherited

Adds a local history entry to this route.

When asked to pop, if this route has any local history entries, this route will handle the pop internally by removing the most recently added local history entry.

The given local history entry must not already be part of another local history route.

The following example is an app with 2 pages: HomePage and SecondPage. The HomePage can navigate to the SecondPage.

The SecondPage uses a LocalHistoryEntry to implement local navigation within that page. Pressing 'show rectangle' displays a red rectangle and adds a local history entry. At that point, pressing the '< back' button pops the latest route, which is the local history entry, and the red rectangle disappears. Pressing the '< back' button a second time once again pops the latest route, which is the SecondPage, itself. Therefore, the second press navigates back to the HomePage.

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: '/',
      routes: {
        '/': (BuildContext context) => HomePage(),
        '/second_page': (BuildContext context) => SecondPage(),
      },
    );
  }
}

class HomePage extends StatefulWidget {
  HomePage();

  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text('HomePage'),
            // Press this button to open the SecondPage.
            RaisedButton(
              child: Text('Second Page >'),
              onPressed: () {
                Navigator.pushNamed(context, '/second_page');
              },
            ),
          ],
        ),
      ),
    );
  }
}

class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {

  bool _showRectangle = false;

  void _navigateLocallyToShowRectangle() async {
    // This local history entry essentially represents the display of the red
    // rectangle. When this local history entry is removed, we hide the red
    // rectangle.
    setState(() => _showRectangle = true);
    ModalRoute.of(context).addLocalHistoryEntry(
        LocalHistoryEntry(
            onRemove: () {
              // Hide the red rectangle.
              setState(() => _showRectangle = false);
            }
        )
    );
  }

  @override
  Widget build(BuildContext context) {
    final localNavContent = _showRectangle
      ? Container(
          width: 100.0,
          height: 100.0,
          color: Colors.red,
        )
      : RaisedButton(
          child: Text('Show Rectangle'),
          onPressed: _navigateLocallyToShowRectangle,
        );

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            localNavContent,
            RaisedButton(
              child: Text('< Back'),
              onPressed: () {
                // Pop a route. If this is pressed while the red rectangle is
                // visible then it will will pop our local history entry, which
                // will hide the red rectangle. Otherwise, the SecondPage will
                // navigate back to the HomePage.
                Navigator.of(context).pop();
              },
            ),
          ],
        ),
      ),
    );
  }
}

Implementation

void addLocalHistoryEntry(LocalHistoryEntry entry) {
  assert(entry._owner == null);
  entry._owner = this;
  _localHistory ??= <LocalHistoryEntry>[];
  final bool wasEmpty = _localHistory.isEmpty;
  _localHistory.add(entry);
  if (wasEmpty)
    changedInternalState();
}