Flutter's Navigation 2.0 doesn't update the UI

Issue

I’m trying to understand how to use Flutter’s declarative navigation system. I want to create a simple app that will add / remove routes to the stack infinitely. Like, "Screen N" has two buttons: first pops it from the stack and second adds "Screen N+1" to the stack. So, I’ve made a stateful widget to hold the Navigator state (pages):

class _MyAppState extends State<MyApp> {
  final List<Page> _pages = <Page>[];

  @override
  void initState() {
    super.initState();
    _dive(0);
  }

  @override
  Widget build(BuildContext context) {
    print(_pages);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Navigator(
        pages: _pages,
        onPopPage: (route, result) {
          route.didPop(result);
          return true;
        },
      ),
    );
  }

  void _arise() {
    setState(() {
      print("Arise!");
      _pages.removeLast();
    });
  }

  void _dive(int value) {
    setState(() {
      print("Dive!");
      _pages.add(
        MaterialPage(
          key: ValueKey(value),
          child: DiveRoute(
            value,
            _arise,
            _dive,
          ),
        ),
      );
    });
  }
}

And here is a "Screen N" widget:

class DiveRoute extends StatelessWidget {
  final int _value;
  final void Function() _arise;
  final void Function(int) _dive;

  const DiveRoute(
    this._value,
    this._arise,
    this._dive, {
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dive"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("$_value"),
            ElevatedButton(
              onPressed: () => _arise(),
              child: Text("Up"),
            ),
            ElevatedButton(
              onPressed: () => _dive(_value + 1),
              child: Text("Down"),
            ),
          ],
        ),
      ),
    );
  }
}

The app correctly draws the first screen (0), but clicking the buttons doesn’t update the UI, although the prints are visible in the console and I see how the list of pages grows and shrinks.

Here is a DartPad

Solution

They use != to compare the pages variable(navigator.dart):

if (oldWidget.pages != widget.pages && !restorePending) {

so you need to provide a new instance every time you update the pages variable.

Answered By – Brave Dolphin

Answer Checked By – Senaida (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.