【问题标题】:How to display a dialog once a screen loads (without onTap) Flutter屏幕加载后如何显示对话框(没有 onTap) Flutter
【发布时间】:2021-03-30 13:57:44
【问题描述】:

我试图在页面加载时显示一个对话框。我有在点击按钮时调用的对话框我尝试使用相同的技术,但出现不同的错误。

这是我的代码的开头部分:

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.

我希望这是有道理的

【问题讨论】:

标签: flutter


【解决方案1】:

将页面转换为有状态小部件并覆盖initState 函数,然后在那里显示对话框。

【讨论】:

  • 现在我收到以下错误:在_SelectAccountState.initState() 完成之前调用了dependOnInheritedWidgetOfExactType<_localizationsscope>() 或dependOnInheritedElement()...
  • @WilliamChidube 这是因为您在进行渲染时尝试在initState 内设置状态。这会导致渲染问题。要克服它,您应该等待初始渲染完成,使用 WidgetsBinding.instance.addPostFrameCallback((_) =&gt; showMyCustomDialog());
【解决方案2】:

不必使用StatefulWidget。在build方法中写下这段代码:

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

此代码将在构建小部件时执行一次。

【讨论】:

  • 我收到此错误:没有为类型定义 getter 'instance'...
  • 嘿@BambinoUA 感谢您的回答。我没有对你投反对票,我不知道是谁投的。我会支持你,因为你的回答也有助于引导我走向最终对我有用的道路。
【解决方案3】:

我找到了这个链接:How to show alert dialog in flutter without button click

我在有状态的小部件中了解到这一点......

  1. 你应该 @override initState() [就像上面的 @Mohammed Abdou 建议的那样]

  2. 像这样在 initState 中调用 SchedulerBinding 类:

    @override
     void initState() {
       super.initState();
    
       SchedulerBinding.instance.addPostFrameCallback((_) { 
         _yourFunction();
       });
     }
    
  3. 非常!重要。您必须导入调度程序包:

    导入'package:flutter/scheduler.dart';

  4. 显然定义你的 _showErrorAlert() 函数。我在一切之外做了我的事。在我的整个代码下方。

注意:我没有在 build 内部做任何这些。

所以基本上,我的代码如下所示:

++++内部_State类:

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

  _ifLoaded() async {
    showAlertDialog(context);
  }

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 2023-01-17
    • 2018-12-27
    • 2020-12-24
    相关资源
    最近更新 更多