Flutter: как открыть диалоговое окно, а также текущую страницу?

Ниже приведен код.

  1. Переход на страницу входа с домашней страницы
    ElevatedButton(
              onPressed: () => Navigator.of(context, rootNavigator: true)
                  .push(MaterialPageRoute(
                fullscreenDialog: true,
                builder: (context) => UserLoginPage(),
              )),
              child: Text('Login to continue'),
            ),

Внутренняя страница входа в систему:

BlocConsumer<UserAuthCubit, UserAuthState>(
            listener: (context, state) {
              if (state is UserAuthorized) {
                Navigator.of(context, rootNavigator: true).pop();
              }
              if (state is UserAuthWaiting) {
                showModalBottomSheet(
                    useRootNavigator: true,
                    isDismissible: false,
                    context: context,
                    builder: (context) {
                      return WillPopScope(
                        onWillPop: () async => false,
                        child: Center(
                          child: Text(state.msg),
                        ),
                      );
                    });
                dialog = true;
              } else {
                if (dialog) {
                  Navigator.of(context, rootNavigator: true).pop();
                  dialog = false;
                }
              }
            },
            builder: (context, state) { // some widget code... }

Когда состояние равно UserAuthorized, я хочу открыть диалоговое окно, а также страницу входа в систему, чтобы вернуться на последнюю страницу, т.е. домашнюю страницу. Однако с приведенным выше кодом иногда это работает, а в другой раз домашняя страница также выскакивает. Я пробовал с / без rootNavigator, установленным на true, но не смог достичь своей цели.

Пожалуйста, помогите мне понять, что мне здесь не хватает.

Я проверил ответ здесь Как закрыть диалоговое окно флаттера?.


person ronbm    schedule 19.08.2020    source источник


Ответы (2)


Вы можете просто использовать

Navigator.popUntil(context, (route) {
            return count++ == 2;
          });

ОБНОВЛЕНИЕ:

Если вы не знаете, сколько страниц вы должны открыть, вам следует использовать

Navigator.push(context, MaterialPageRoute(builder: (context)=>YourMaterialClassName(), settings: RouteSettings(name: "nameOfYourClass")));

пока вы продвигаете свой материальный класс.

затем во время всплывающего окна используйте

Navigator.popUntil(context, (route) => route.settings.name == "nameOfYourClass");
person Tipu Sultan    schedule 19.08.2020
comment
Я действительно мог бы воспользоваться твоим предложением. Помогло чуть глубже покопаться в механизме. Я попробовал второй код (который, как мне кажется, чище). Однако я мог бы достичь своей цели с помощью дополнительного Navigator.pop (context) после Navigator.popUntil, так как все маршруты появляются, кроме моей страницы входа. Я думаю, что Navigator.popUntil означает, что маршруты будут появляться и останавливаться, когда предикат вернет истину; поэтому он останавливается на странице входа в систему. Сообщите мне, правильно ли я думаю. - person ronbm; 19.08.2020

Я предлагаю после диалога вернуть true вместо использования Navigator.of(context).pop().

Или вы можете попробовать использовать

Navigator.of(context).pushReplacement(
  MaterialPageRoute(builder: (context) => HomePage()),
)

Таким образом вы замените LoginPage на HomePage.

person Aldy Yuan    schedule 19.08.2020
comment
pushReplacement очищает backstack. Например, пользователь переходит с экрана 1 ›экрана 2 с диалоговым окном -› экрана 3. Вызов Navigator.pop () на экране 3 приведет к пустому / черному экрану, поскольку история перехода с экрана 1 на экран 2 очищается. Он не может вернуться на экран 2 или 1. - person Uni; 19.08.2020
comment
Я имею в виду, почему вы все равно вернетесь к LoginPage, если вы не вышли из системы IMO, но если в этом случае вы не очистите историю экрана, то я не предлагаю этот ответ - person Aldy Yuan; 19.08.2020
comment
Это правда, но что, если он захочет Navigator.pop (). Есть причина, по которой нужно использовать Navigator.pop (). Тбх, ему вообще не следует использовать навигатор, чтобы покидать страницу входа. Он должен использовать потоки, чтобы получить текущее состояние входа пользователя. Я тоже понимаю вашу точку зрения, @Aldy Yuan, но мы должны дать ему возможность вызвать Navigator.pop (), когда он захочет. - person Uni; 19.08.2020
comment
Я согласен с тем, что использование stream было бы намного проще и избегало шаблонов, и также я согласен с ним, что он хочет Navigator.pop () вместо pushReplacements. Это единственное предложение пришло мне в голову, я все равно удалю его, спасибо - person Aldy Yuan; 19.08.2020
comment
Вы можете оставить здесь свой ответ. он может использовать ваш ответ, если захочет. - person Uni; 19.08.2020
comment
Я использую это для другого варианта использования, в том же приложении, для которого я разместил вопрос, для маршрутов равного ранга, но исключающих друг друга. - person ronbm; 19.08.2020