首页 > 解决方案 > 如何在颤动中自动启动某些东西

问题描述

我有以下代码,最初显示一个空白页,但我希望自动显示一个 rAlert 对话框。一旦用户单击“请求”或“取消”,屏幕上将显示一些文本。

但我无法运行显示警报的代码。我通过显示一个按钮并单击该按钮使其工作,但是我需要在显示页面时自动显示警报。我试着把它放在 initState 中。我没有收到任何错误,但它也没有工作。

有人知道我需要做什么吗?谢谢?

import 'package:flutter/material.dart';
import 'package:rflutter_alert/rflutter_alert.dart';
import 'dart:async';
import 'package:rostermeon/cwidgets/general_widgets.dart';
import 'package:rostermeon/rmo_constants.dart';

class ForgotPassword extends StatefulWidget {
  static const String id = 'forgot_password_screen';

  @override
  _ForgotPasswordState createState() => _ForgotPasswordState();
}

class _ForgotPasswordState extends State<ForgotPassword> {
  StreamController<bool> _events;

  @override
  initState() {
    super.initState();
    _events = new StreamController<bool>();
    doRequest(context: context);
  }

  Future<bool> doSaveRequest({String pReason}) async {
    await Future.delayed(const Duration(seconds: 3), () {});
    return false;
  }

  Future<bool> doRequest({context}) {
    String _reason = '';
    GlobalKey<FormState> _formKey = GlobalKey<FormState>();

    TextEditingController reasonController = TextEditingController();

    TextStyle _style = TextStyle(fontFamily: 'Montserrat', fontSize: 18.0, fontWeight: FontWeight.normal);

    InputDecoration _textFormFieldDecoration({String hintText, double padding}) => InputDecoration(
          //contentPadding: EdgeInsets.fromLTRB(8.0, 8.0, 8.0, 8.0),
          contentPadding: EdgeInsets.all(padding),
          isDense: true,
          hintText: hintText,
          hintStyle: TextStyle(color: kHintText),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ),
        );

    return Alert(
      context: context,
      title: 'Request New Password',
      content: StreamBuilder<bool>(
          initialData: false,
          stream: _events.stream,
          builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
            print(" ${snapshot.data.toString()}");
            return snapshot.data
                ? CircularProgressIndicator()
                : Form(
                    key: _formKey,
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: <Widget>[
                        SizedBox(height: 20.0),
                        Text('Email', textAlign: TextAlign.left, style: _style),
                        SizedBox(height: 10.0),
                        TextFormField(
                          validator: (value) {
                            if (value.isEmpty) {
                              return "please enter email";
                            }
                            return null;
                          },
                          onSaved: (value) {
                            _reason = value;
                          },
                          decoration: _textFormFieldDecoration(
                            hintText: 'your email address',
                            padding: 8.0,
                          ),
                          controller: reasonController,
                        ),
                        SizedBox(height: 10.0),
                      ],
                    ),
                  );
          }),
      buttons: [
        DialogButton(
          child: Text('Request', style: TextStyle(color: Colors.white, fontSize: 20)),
          color: kMainColor,
          onPressed: () async {
            if (_formKey.currentState.validate()) {
              _formKey.currentState.save();
              print(_reason);

              _events.add(true);

              var saved = await doSaveRequest(pReason: _reason);
              if (saved) {
                Navigator.pop(context, false);
              } else {
                _events.add(false);
              }
              Navigator.of(context).pop();
//              Navigator.pop(context, false);
            }
          },
        ),
        DialogButton(
          child: Text('Cancel', style: TextStyle(color: Colors.white, fontSize: 20)),
          color: kMainColor,
          onPressed: () {
            Navigator.pop(context, false);
          },
        ),
      ],
    ).show();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: rmoAppBar(subText: 'Request New Password', hideBackButton: false),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[],
        ),
      ),
    );
  }
}

标签: flutter

解决方案


对话框/警报需要 buildContext 才能工作,在调用 build() 方法之前你不能拥有 buildContext,这就是为什么你不能在调用 build 之前在 initstate() 中调用它。要使其正常工作,请使用 addPostFrameCallback 以确保它延迟到构建小部件:

  void initState() {
    super.initState();
    WidgetsBinding.instance
        .addPostFrameCallback((_) => yourMethod(context));
  }

https://www.didierboelens.com/2019/04/addpostframecallback/


推荐阅读