【问题标题】:How to call showDialog after page load without doing any action?页面加载后如何在不执行任何操作的情况下调用 showDialog?
【发布时间】:2022-07-12 00:00:27
【问题描述】:

告诉我,我有一个页面,我需要在页面加载后显示dialog,但我需要它在页面加载后而不是在点击时自行打开。我尝试将showDialog 方法添加到initState,但出现错误。页面加载后如何显示对话框?

对话框

showDialog(
    context: context,
    builder: (BuildContext context) => const SendEmailDialog(),
);

正文

class Body extends StatefulWidget {
  const Body({Key? key, this.isUserAuth = false}) : super(key: key);

  final bool isUserAuth;

  @override
  State<Body> createState() => _BodyState();
}

class _BodyState extends State<Body> {
  bool isMapList = false;

  @override
  Widget build(BuildContext context) {
    final Size size = MediaQuery.of(context).size;
    final double paddingTop = MediaQuery.of(context).padding.top;
    return BlocBuilder<StationCubit, StationState>(
      builder: (context, state) {
        final StationCubit cubit = BlocProvider.of<StationCubit>(context);
        return BlocBuilder<StationMarkerCubit, StationMarkerState>(
          builder: (context, stationMarkerState) {
            final StationMarkerCubit stationMarkerCubit =
                BlocProvider.of<StationMarkerCubit>(context);
            return Container(
              height: size.height,
              width: size.width,
              decoration: isMapList
                  ? const BoxDecoration(
                      gradient: LinearGradient(
                        begin: Alignment.topCenter,
                        end: Alignment.bottomCenter,
                        colors: [
                          constants.Colors.blue7xDark,
                          constants.Colors.blue6xDark,
                          constants.Colors.blueXxxxxDark,
                        ],
                      ),
                    )
                  : const BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage(
                            'assets/images/background/main_background.png'),
                        fit: BoxFit.cover,
                      ),
                    ),
              child:
                  _child(context, size, cubit, stationMarkerCubit, paddingTop),
            );
          },
        );
      },
    );
  }

  Widget _child(BuildContext context, Size size, StationCubit cubit,
          StationMarkerCubit stationMarkerCubit, double paddingTop) =>
      Stack(
        alignment: AlignmentDirectional.bottomCenter,
        children: [
          isMapList
              ? const SizedBox()
              : GestureDetector(
                  onTap: () {
                    cubit.selectStation(null);
                  },
                  child: MapWidget(
                    stationCubit: cubit,
                    stationMarkerCubit: stationMarkerCubit,
                    isUserAuth: widget.isUserAuth,
                  ),
                ),
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 20),
            child: Column(
              children: [
                SizedBox(
                  height: paddingTop + 24,
                ),
                SizedBox(
                  height: 45,
                  child: SearchWidget(
                    isMapList: isMapList,
                    isMapListChanged: (value) => setState(() {
                      isMapList = value;
                      _onDismissedStationCard(stationMarkerCubit, cubit);
                    }),
                    isUserAuth: widget.isUserAuth,
                  ),
                ),
                const SizedBox(
                  height: 24,
                ),
                isMapList ? const MapListWidget() : const SizedBox(),
                isMapList
                    ? const SizedBox(height: 0)
                    : const SizedBox(height: 100)
              ],
            ),
          ),

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    您可以在 initState 上使用addPostFrameCallback

      @override
      void initState() {
        super.initState();
        WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
          showDialog(
            context: context,
            builder: (BuildContext context) => AlertDialog(),
          );
        });
      }
    

    【讨论】:

    • 领带跑者 :)
    • 是的,我已经在测试后发布,并且在 Flutter 3 上 instance 不可为空。
    • 我也是。这意味着我们俩同时回答了
    • 谢谢它有效:)
    • @Max 我没关系。继续接受他的回答:)
    【解决方案2】:

    你可以使用WidgetsBinding.instance?.addPostFrameCallback():

    void initState() {
        // TODO: implement initState
        WidgetsBinding.instance?.addPostFrameCallback((_) {
          showDialog(
              context: context,
              builder: (context) => AlertDialog(
                    title: Text('Hello'),
                    content: Text('Hello World'),
                  ));
        });
    
        super.initState();
      }
    

    【讨论】:

    • 谢谢,这有帮助:)
    • 谢谢,这有帮助。我还可以指定额外的时间,让它在 2-3 秒后显示吗?
    • @Max 尝试使用Future.delayed()
    • 我需要在 addPostFrameCallback 中指定这个吗?
    • @Max 其实我觉得如果你用Future.delayed你可能甚至不需要addpostframback你可以试试
    猜你喜欢
    • 2014-01-17
    • 2019-11-22
    • 1970-01-01
    • 2015-09-15
    • 2011-10-31
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    • 2012-09-30
    相关资源
    最近更新 更多