K-Dawg
K-Dawg

Reputation: 3299

Flutter: Build is not called when navigation popped

I've been using the provider library for a little while now, trying to get to grips with it.

I recently ran into an issue with Navigation.

In my app I have an "order" containing products held in my provider state (appState). The order is built up in the menu view. I then move to the "product review" screen using this code:

 Navigator.push(
        context,
        PageRouteBuilder(
          transitionDuration: transitionDuration == null
              ? Duration(
                  milliseconds: appState.settings
                      .standardPageNavigationDuration) // standard app duration
              : transitionDuration,
          pageBuilder: (_, __, ___) => Provider<TrinoAppState>.value(
            child: view,
            value: appState,
          ),
        ), 

The user can modify quantities of products in the order review screen. If for example a quantity is edited and then the order (held in the app state) is updated.

The Problem

The problem I have is that when the user clicks back from the order review, the build function on the menu screen does not seem to get triggered so it does not update (still shows old price despite removed items in the order).

I'm not sure what the best way to tackle this problem is, Do you have any suggestions?

Upvotes: 1

Views: 1438

Answers (1)

Lulupointu
Lulupointu

Reputation: 3584

An easy yet effective solution would be to call setState when you use pop (I assume it's what you do to get back to the first page).

This would look like this:

  Navigator.push(
    context,
    PageRouteBuilder(
      transitionDuration: transitionDuration == null
          ? Duration(
              milliseconds:
                  appState.settings.standardPageNavigatoinDuration) // standard app duration
          : transitionDuration,
      pageBuilder: (_, __, ___) => Provider<TrinoAppState>.value(
        child: view,
        value: appState,
      ),
    ),
  ).whenComplete(() => setState((){})),

Here is a small working example. The whenComplete method is called in three cases:

  1. You call Navigator.pop (this happens when you click the FAB)
  2. The back button in the appBar (which implicitly calls Navigator.pop tbh)
  3. Pressing the back button of the phone
import 'dart:math';

import 'package:flutter/material.dart';

main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First page'),
      ),
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.red,
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => SecondRoute()),
          ).whenComplete(() => print('POP'));
        },
      ),
    );
  }
}

class SecondRoute extends StatefulWidget {
  @override
  _SecondRouteState createState() => _SecondRouteState();
}

class _SecondRouteState extends State<SecondRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second page'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}

Upvotes: 2

Related Questions