Flutter 如何在颤振应用程序的initState期间使用来自提供程序的数据

Flutter 如何在颤振应用程序的initState期间使用来自提供程序的数据,flutter,flutter-layout,state-management,flutter-provider,flutter-state,Flutter,Flutter Layout,State Management,Flutter Provider,Flutter State,我正在通过添加提供程序作为状态管理来重构我的flatter应用程序代码 所需行为:当主屏幕打开时,应用程序应检查用户的电子邮件是否已验证,如果未验证,则应显示对话框弹出窗口 问题:当我通过构造函数传递EmailVerified的数据时,它工作正常,但如果我想使用提供程序,我无法在initState()生命周期中获取此数据 您能为我推荐这种用例的正确方法吗 import 'package:myapp/services/authentication.dart'; import 'package:my

我正在通过添加提供程序作为状态管理来重构我的flatter应用程序代码

所需行为:当主屏幕打开时,应用程序应检查用户的电子邮件是否已验证,如果未验证,则应显示对话框弹出窗口

问题:当我通过构造函数传递EmailVerified的数据时,它工作正常,但如果我想使用提供程序,我无法在
initState()
生命周期中获取此数据

您能为我推荐这种用例的正确方法吗

import 'package:myapp/services/authentication.dart';
import 'package:myapp/screens/settings_screen.dart';
import 'package:flutter/material.dart';
import 'package:myapp/services/authentication.dart';
import 'package:provider/provider.dart';

class HomeScreen extends StatefulWidget {

  @override
  State<StatefulWidget> createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  bool _isEmailVerified = false;

  @override
  void initState() {
    super.initState();
    _checkEmailVerification(); // <=== Method which should show Dialog box if email is not verified which is coming from "Auth" Provider
  }

  @override
  Widget build(BuildContext context) {
    final auth = Provider.of<Auth>(context, listen: false); // <==== Service from Provider, which contains data for _isEmailVerified
    auth.isEmailVerified().then((value) => _isEmailVerified = value);

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('My App'),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            Text(
              'Welcome to my app',
            ),
          ],
        ),
      ),
    );
  }

  void _checkEmailVerification() async {
    _isEmailVerified = auth.isEmailVerified(); // <=== How can I use "auth" from Provider to get isEmailVerified data ????
    if (!_isEmailVerified) {
      _showVerifyEmailDialog();
    }
  }

  void _showVerifyEmailDialog() {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        // return object of type Dialog
        return AlertDialog(
          title: new Text("Verify your account"),
          content: new Text("Please verify account in the link sent to email"),
          actions: <Widget>[
            new FlatButton(
              child: new Text("Resend link"),
              onPressed: () {
                Navigator.of(context).pop();
                _resentVerifyEmail();
              },
            ),
            new FlatButton(
              child: new Text("Dismiss"),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  void _resentVerifyEmail() {
    // Logic to send email
  }
}

import'包:myapp/services/authentication.dart';
导入“package:myapp/screens/settings_screen.dart”;
进口“包装:颤振/材料.省道”;
导入“包:myapp/services/authentication.dart”;
导入“包:provider/provider.dart”;
类主屏幕扩展StatefulWidget{
@凌驾
State createState()=>新的_homescrenstate();
}
类_homescrenstate扩展状态{
最终GlobalKey formKey=GlobalKey();
bool _isEmailVerified=false;
@凌驾
void initState(){
super.initState();

_checkEmailVerification();//您需要使用上下文来调用
Provider.of()
,这样您就可以添加
addPostFrameCallback()
,它在第一次生成后被调用,在那里您可以使用上下文

@override
void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      auth = Provider.of<Auth>(context, listen: false);
    });
}
@覆盖
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((时间戳){
auth=Provider.of(上下文,侦听:false);
});
}

提供程序v4.1.0
中,您还可以使用方法。它减少了样板代码

@override
void initState() {
  super.initState();

  WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
    auth = context.read<Auth>();
  });
}
@覆盖
void initState(){
super.initState();
WidgetsBinding.instance.addPostFrameCallback((时间戳){
auth=context.read();
});
}

在3.0.0+1版中,您也可以

你可以用它来做

var CallNotifier auth;


@override
void initState(){
 super.initState();
 auth = Provider.of<CallNotifier>(context, listen = false);
}
var CallNotifier auth;
@凌驾
void initState(){
super.initState();
auth=Provider.of(上下文,listen=false);
}

您还可以将
上下文
传递到
主屏幕
小部件,该小部件将允许您访问
提供者

class HomeScreen extends StatefulWidget {
  final BuildContext context;
  HomeScreen(this.context);

  @override
  State<StatefulWidget> createState() => new _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _isEmailVerified = false;

  void _checkEmailVerification() async {
    _isEmailVerified = widget.context.read<Auth>().isEmailVerified();
    if (!_isEmailVerified) {
      _showVerifyEmailDialog();
    }
  }

...

}
类主屏幕扩展StatefulWidget{
最终构建语境;
主屏幕(这个上下文);
@凌驾
State createState()=>新的_homescrenstate();
}
类_homescrenstate扩展状态{
bool _isEmailVerified=false;
void\u checkEmailVerification()异步{
_isEmailVerified=widget.context.read().isEmailVerified();
如果(!\u已验证){
_showVerifyEmailDialog();
}
}
...
}

非常感谢@Sebastian。另外,如果有其他人面临这个问题,我推荐下面的文章,它解释了为什么
showDialog
不能像您预期的那样工作,以及什么是
addPostFrameCallback()
needed for-@Sebastian这在Android中有效,而不是在iOS中。在iOS中抛出错误未经处理的异常:“package:provider/src/provider.dart”:失败的断言:第240行位置12:“context!=null”:不正确。谢谢。这真的有效吗?还是我遗漏了什么?我的用户在构建期间未初始化,而dart抛出了一个错误。我我在
addPostFrameCallback()中使用
Provider.of(context,listen:false).currentUser