Запретить Navigator.push, если пользователь нажимает кнопку возврата

В моем приложении мне нужно выполнить код перед вызовом Navigator.push. Но проблема в том, что если пользователь нажимает кнопку "Назад" до выполнения кода, возникает ошибка:

E/flutter (8415): [ОШИБКА:flutter/lib/ui/ui_dart_state.cc(148)] Необработанное исключение: поиск предка деактивированного виджета небезопасен. E/flutter ( 8415): в этот момент состояние дерева элементов виджета больше не стабильно. E/flutter ( 8415): чтобы безопасно ссылаться на предка виджета в его методе dispose (), сохраните ссылку на предка, вызвав inheritFromWidgetOfExactType() в методе didChangeDependencies() виджета.

Проблема в том, что код все еще выполняется и Navigator.push вызывается, даже если пользователь нажимает кнопку возврата (в Widget2).

Вот mwe:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Widget1(),
    );
  }
}

class Widget1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: RaisedButton(
          onPressed: () async {
            await Navigator.push(
                context,
                MaterialPageRoute(
                  builder: (context) => Widget2(),
                ));
          },
        ),
      ),
    );
  }
}

class Widget2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: RaisedButton(
      onPressed: () async {
//      Press back button before Future complete
        await Future.delayed(Duration(seconds: 5));
        await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => Widget3(),
            ));
      },
    ));
  }
}

class Widget3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(child: Text('Widget 3'));
  }
}

1 ответ

В зависимости от того, чего вы хотите, вы можете сделать несколько вещей:

  • Чтобы заменить текущее представление новым, не давая пользователям возможности вернуться на предыдущую страницу, используйтеNavigator.pushReplacement(...)
  • Чтобы на панели приложения отображалась кнопка "Назад", но пользователи не могли вернуться назад, обернитеScaffoldс WillPopScope и сделайтеonWillPop свойство вернуть Future.value(false).
  • Чтобы просто скрыть кнопку "Назад", выполните:AppBar(...,automaticallyImplyLeading: false,...). Пользователи по-прежнему смогут вернуться, нажав кнопку "Назад" в Android или проведя пальцем по экрану в iOS.
Другие вопросы по тегам