Обновленные значения переопределяются при перерисовке виджета - PullRequest
0 голосов
/ 04 октября 2019

Я играю с простым приложением обратного отсчета флаттера. Он состоит из 2 страниц, часов и страницы настроек для установки минут и секунд для обратного отсчета.

На странице часов (HomeWidget) пользователь нажимает кнопку, чтобы перейти на страницу настроек. После редактирования значений пользователь нажимает аппаратную клавишу «Назад» или кнопку на панели приложения, чтобы вернуться на страницу часов.

class _HomeWidgetState extends State<HomeWidget> {
@override
Widget build(BuildContext context) {
  TimeService _timeService = ScopedModel.of<TimeService>(context);
  SettingsModel _settingsModel = ScopedModel.of<SettingsModel>(context);
  _timeService.setTime(_settingsModel.minutes, _settingsModel.seconds);

return Scaffold( ... display the clock, navigation buttons, etc ... )}

Моя проблема в том, что при переходе назад я устанавливаю новые значенияв классе обслуживания времени, который обрабатывает обратный отсчет. Но в примере кода служба времени обновляется каждый раз, когда часы перерисовываются (каждую секунду). Обратный отсчет не работает, значение остается прежним. Вместо отображения «10:29», он придерживается «10:30». Я не знаю, как обрабатывать зависимость между моим классом TimeService и моим классом SettingsModel.

Как правильно обрабатывать присвоение значений настроек в классе обслуживания времени, когда пользователь переходит обратно? Метод build явно не в том месте. Кто-нибудь может дать мне подсказку?

1 Ответ

0 голосов
/ 05 октября 2019

Хорошо, я нашел решение для моей проблемы. Это подробно описано (с некоторым другим содержанием) здесь .

В основном при навигации по страницам вы можете передавать объекты вдоль. Так что теперь я просто передаю отредактированную SettingsModel на странице настроек с помощью команды Navigator.of(context).pop({'newSetting': _settingsModel});, и страница часов обрабатывает результат. Я не знал, что навигация работает следующим образом.

ControlButtonWidget(
        icon: Icons.settings,
        iconSize: 72.0,
        onPressedHandler: () async {
          Map results = await Navigator.of(context).push(
              new MaterialPageRoute(
                  builder: (context) => SettingsWidget(model)));

          if (results != null && results.containsKey("newSetting")){
            SettingsModel model = results["newSetting"];
            ScopedModel.of<TimeService>(context).setTime(model.minutes, model.seconds);
          }
        })

Оберните свою страницу в WillPopScope Widget .

@override
Widget build(BuildContext context) {
return new WillPopScope(
    onWillPop: _backRequestedHandler,
    child: LayoutBuilder(builder:
        (BuildContext context, BoxConstraints viewportConstraints) {
      return Scaffold(
          appBar: new AppBar(title: Text("Settings")),
          body: ...

    }));
}

Future<bool> _backRequestedHandler() {
  Navigator.of(context).pop({'newSetting': _settingsModel});
  return new Future.value(true);
} 
...