Flutter: сборка не вызывается при появлении навигации

#flutter #dart #flutter-provider

#флаттер #дротик #flutter-provider

Вопрос:

Я уже некоторое время использую библиотеку провайдера, пытаясь разобраться с ней. Недавно я столкнулся с проблемой с навигацией.

В моем приложении у меня есть «заказ», содержащий продукты, хранящиеся в моем состоянии поставщика (AppState). Порядок создается в представлении меню. Затем я перехожу к экрану «обзор продукта», используя этот код:

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

Пользователь может изменять количество продуктов на экране просмотра заказа. Если, например, редактируется количество, а затем обновляется заказ (сохраняемый в состоянии приложения).

Проблема

Проблема, с которой я сталкиваюсь, заключается в том, что, когда пользователь переходит от просмотра заказа, функция сборки на экране меню, похоже, не запускается, поэтому она не обновляется (все еще показывает старую цену, несмотря на удаленные элементы в заказе).

Я не уверен, как лучше всего решить эту проблему, есть ли у вас какие-либо предложения?

Комментарии:

1. на самом деле вы просто открываете текущий вид, под ним будет отображаться нижний вид. быстрое решение — использовать Navigator.push / pushNamed(), а не pop, поскольку он вызовет метод initState ..

Ответ №1:

Простым, но эффективным решением было бы вызвать setState при использовании pop (я предполагаю, что это то, что вы делаете, чтобы вернуться на первую страницу).

Это будет выглядеть так:

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

Вот небольшой рабочий пример. whenComplete Метод вызывается в трех случаях:

  1. Вы вызываете Navigator.pop (это происходит при нажатии на FAB)
  2. Кнопка «Назад» в appBar (которая неявно вызывает Navigator.pop tbh)
  3. Нажатие кнопки «Назад» на телефоне
 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);
        },
      ),
    );
  }
}
  

Комментарии:

1. Это работает для перехода к представлению. Моя проблема в том, что на телефоне нажата кнопка «Назад», и поэтому на данный момент я не осуществляю навигацию.

2. Для меня нажатие кнопки «Назад» вызывает нажатие при нажатии. Пожалуйста, попробуйте мой пример для подтверждения.

3. Просто попробовал это в моем проекте, и это работает! Большое вам спасибо.