Как отобразить диалог после загрузки экрана (без onTap) Flutter

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

Вот начальная часть моего кода:

class SelectAccount extends StatelessWidget {
  final globalKey = GlobalKey<ScaffoldState>();
  @override
  Widget build(BuildContext context) {
    return ScopedModel(
        model: userModel,
        child: ScopedModelDescendant<UserModel>(builder:
            (BuildContext inContext, Widget inChild, UserModel inModel) {
          return Scaffold(
              key: globalKey,
              extendBodyBehindAppBar: true,
              appBar: AppBar(),
              body: Stack(children: [
                Background(),
                Column(
                  children: [
                    Container(
                      padding: EdgeInsets.only(
                          top: 15 * SizeConfig.heightMultiplier),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.end,
                        children: [
                          Text(
                            'Please select',
                            style: Theme.of(context).textTheme.headline3,
                          ),
                        ],
                      ),
                      //color: Colors.red,
                    ),
                    Expanded(
                        flex: 2,
                        child: Column(...

Где я могу определить эту функцию перед ее вызовом? Нужен ли мне initState()?

showAlertDialog(BuildContext context) {
  // set up the buttons
  Widget cancelButton = FlatButton(
    child: Text("Cancel"),
    onPressed: () {},
  );
  Widget continueButton = FlatButton(
    child: Text("Continue"),
    onPressed: () {},
  );

  // set up the AlertDialog
  AlertDialog alert = AlertDialog(
    title: Text("AlertDialog"),
    content:
        Text("Information here"),
    actions: [
      cancelButton,
      continueButton,
    ],
  );

  // show the dialog
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return alert;
    },
  );
}

Используя его следующим образом:

                                    TextSpan(
                                        text: ' Sign in',
                                        style: TextStyle(
                                          color: buttonColor,
                                          fontSize: 14.0,
                                        ),
                                        recognizer: TapGestureRecognizer()
                                          ..onTap = () {
                                            Navigator.of(context)
                                                .pushReplacementNamed(
                                                    '/signin');
                                          })
                                  ]),
                            ),
                          ],
                        )),
                    Container(
                      padding: EdgeInsets.symmetric(vertical: 70),
                    )
                  ],
                ),
                showAlertDialog(context)
              ]));
        }));
  }
}

showAlertDialog(BuildContext context) {
  // set up the buttons
  Widget cancelButton = FlatButton(
    child: Text("Cancel"),
    onPressed: () {},
  );
  Widget continueButton = FlatButton(
    child: Text("Continue"),
    onPressed: () {},
  );

  // set up the AlertDialog
  AlertDialog alert = AlertDialog(
    title: Text("AlertDialog"),
    content:
        Text("Would you like to continue learning how to use Flutter alerts?"),
    actions: [
      cancelButton,
      continueButton,
    ],
  );

  // show the dialog
  showDialog(
    context: context,
    builder: (BuildContext context) {
      return alert;
    },
  );
}

...выдает следующую ошибку:

I/flutter ( 4658): RESPONSE []
E/flutter ( 4658): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 2416 pos 18: '!navigator._debugLocked': is not true.
E/flutter ( 4658): #0      _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
E/flutter ( 4658): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
E/flutter ( 4658): #2      _RouteEntry.handlePush.<anonymous closure> (package:flutter/src/widgets/navigator.dart:2416:18)
E/flutter ( 4658): #3      TickerFuture.whenCompleteOrCancel.thunk (package:flutter/src/scheduler/ticker.dart:399:15)
E/flutter ( 4658): #4      _rootRunUnary (dart:async/zone.dart:1198:47)
E/flutter ( 4658): #5      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4658): #6      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
E/flutter ( 4658): #7      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
E/flutter ( 4658): #8      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
E/flutter ( 4658): #9      Future._completeWithValue (dart:async/future_impl.dart:529:5)
E/flutter ( 4658): #10     Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
E/flutter ( 4658): #11     _rootRun (dart:async/zone.dart:1190:13)
E/flutter ( 4658): #12     _CustomZone.run (dart:async/zone.dart:1093:19)
E/flutter ( 4658): #13     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
E/flutter ( 4658): #14     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
E/flutter ( 4658): #15     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
E/flutter ( 4658): #16     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
E/flutter ( 4658):
I/flutter ( 4658): Another exception was thrown: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 3524 pos 12: '!_debugLocked': is not true.
I/flutter ( 4658): Another exception was thrown: 'package:flutter/src/widgets/navigator.dart': Failed assertion: line 3524 pos 12: '!_debugLocked': is not true.

Я надеюсь в этом есть смысл

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
1 616
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Преобразуйте страницу в виджет с отслеживанием состояния и переопределите функцию initState, а затем покажите там диалоговое окно.

Теперь я получаю следующую ошибку: dependOnInheritedWidgetOfExactType<_LocalizationsScope>() или dependOnInheritedElement() был вызван до завершения _SelectAccountState.initState()...

William Chidube 20.12.2020 17:53

@WilliamChidube это потому, что вы пытаетесь установить состояние внутри initState во время рендеринга. Это вызывает проблемы с рендерингом. Чтобы преодолеть это, вы должны дождаться завершения первоначального рендеринга, используя WidgetsBinding.instance.addPostFrameCallback((_) => showMyCustomDialog());

Mohamed Abdou 21.12.2020 09:38

Не обязательно использовать StatefulWidget. В методе build напишите этот код:

WidgetsBinding.instance.addPostFrameCallback((_) {
  showDialog(context: context, builder: (_) => alert);
});

Этот код будет выполняться один раз при построении виджета.

Я получаю эту ошибку: "Экземпляр" геттера не определен для типа...

William Chidube 20.12.2020 18:04

Hey@BambinoUA Спасибо за ваш ответ. Я не минусовал тебя, не знаю кто. Я проголосую за вас, поскольку ваш ответ также помог мне на пути к тому пути, который в конечном итоге сработал для меня.

William Chidube 20.12.2020 19:47
Ответ принят как подходящий

Я нашел эту ссылку: Как показать диалоговое окно предупреждения во флаттере без нажатия кнопки

Там я узнал, что в виджете с состоянием...

  1. Вы должны @override initState() [так же, как @Mohammed Abdou выше предложил]

  2. Вызовите класс SchedulerBinding внутри initState следующим образом:

    @override
     void initState() {
       super.initState();
    
       SchedulerBinding.instance.addPostFrameCallback((_) { 
         _yourFunction();
       });
     }
    
  3. Очень важно. Вы должны импортировать пакет планировщика:

    импортировать 'пакет: флаттер/scheduler.dart';

  4. Очевидно, определите свою функцию _showErrorAlert(). Я сделал свое вне всего. Ниже весь мой код.

ПРИМЕЧАНИЕ. Я не делал ничего из этого внутри сборки.

В общем, мой код выглядит так:

++++Внутри класса _State:

  @override
  void initState() {
    super.initState();
    SchedulerBinding.instance.addPostFrameCallback((_) {
    
      _ifLoaded();
    });
  }

  _ifLoaded() async {
    showAlertDialog(context);
  }

Я надеюсь, что это полезно

Другие вопросы по теме