【问题标题】:Failed assertion: line 5070 pos 12: '<optimized out>': is not true断言失败:第 5070 行 pos 12: '<optimized out>': is not true
【发布时间】:2021-03-07 03:41:14
【问题描述】:

用户成功登录并保存状态后,我想隐藏登录屏幕并加载主屏幕,但最终出现错误

以下断言被抛出构建 导航器-[GlobalObjectKey _WidgetsAppState#6686e](脏,依赖项:[UnmanagedRestorationScope,HeroControllerScope],状态: NavigatorState#c7e9f(代码:跟踪 1 个代码)): 'package:flutter/src/widgets/navigator.dart':断言失败:行 5070 pos 12: '': 不正确。

在令牌仍然有效时隐藏登录屏幕的正确方法是什么,只加载主屏幕?

我的代码

Main.dart

    class _MyAppState extends State<MyApp> {
 
       @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'What',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
        scaffoldBackgroundColor: Palette.scaffold,
      ),
      // home: SignIn(),
      routes: {
        //Homepage and being controled by PagesProvider
        '/': (context) => SignIn(),
        'nav': (context) => NavScreen(),
        // add all routes with names here
      },
    );
  }
}

我的登录.dart

class SignIn extends StatefulWidget {
  const SignIn({Key key}) : super(key: key);

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

class _SignInState extends State<SignIn> {
  ProgressDialog progressDialog;

  MsalMobile msal;
  bool isSignedIn = false;
  bool isLoading = true;

  @override
  void initState() {
    super.initState();
    MsalMobile.create('assets/auth_config.json', authority).then((client) {
      setState(() {
        msal = client;
      });
      refreshSignedInStatus();
    });
  }

  /// Updates the signed in state

  refreshSignedInStatus() async {
    bool loggedIn = await msal.getSignedIn();
    if (loggedIn) {
      isSignedIn = loggedIn;
      if (isSignedIn) {
        dynamic data = await handleGetAccount();
        dynamic token = await handleGetTokenSilently();
        dynamic result = token;
        SharedPreferences sharedPreferences =
            await SharedPreferences.getInstance();
        sharedPreferences.get("username");
        sharedPreferences.get("token");
        print('access token (truncated): ${result.accessToken}');
        Navigator.of(context).pop();
        Navigator.of(context).pushReplacement(
          MaterialPageRoute(
            builder: (context) => NavScreen(),
          ),
        );
      }
      // Remaining code for navigation
    }
  }

  /// Gets a token silently.
  Future<dynamic> handleGetTokenSilently() async {
    String authority = "https://login.microsoftonline.com/$TENANT_ID";
    final result = await msal.acquireTokenSilent([SCOPE], authority);
    if (result != null) {
      // print('access token (truncated): ${result.accessToken}');
      SharedPreferences sharedPreferences =
          await SharedPreferences.getInstance();
      sharedPreferences.setString("token", result.accessToken);
      return result;
    } else {
      print('no access token');
      return null;
    }
  }

  /// Signs a user in
  handleSignIn() async {
    await msal.signIn(null, [SCOPE]).then((result) {
      // ignore: unnecessary_statements
      refreshSignedInStatus();
    }).catchError((exception) {
      if (exception is MsalMobileException) {
        logMsalMobileError(exception);
      } else {
        final ex = exception as Exception;
        print('exception occurred');
        print(ex.toString());
      }
    });
  }

  logMsalMobileError(MsalMobileException exception) {
    print('${exception.errorCode}: ${exception.message}');
    if (exception.innerException != null) {
      print(
          'inner exception = ${exception.innerException.errorCode}: ${exception.innerException.message}');
    }
  }

  /// Signs a user out.
  handleSignOut() async {
    try {
      print('signing out');
      await msal.signOut();
      print('signout done');
      refreshSignedInStatus();
    } on MsalMobileException catch (exception) {
      logMsalMobileError(exception);
    }
  }

  /// Gets the current and prior accounts.
  Future<dynamic> handleGetAccount() async {
    // <-- Replace dynamic with type of currentAccount
    final result = await msal.getAccount();
    if (result.currentAccount != null) {
      SharedPreferences sharedPreferences =
          await SharedPreferences.getInstance();
      sharedPreferences.setString("username", result.currentAccount.username);
      //print(result.currentAccount.username);
      return result.currentAccount;
    } else {
      print('no account found');
      return null;
    }
  }

  @override
  Widget build(BuildContext context) {
    progressDialog  = ProgressDialog(context, type:ProgressDialogType.Normal, isDismissible: false, );
    return MaterialApp(
        home: new Scaffold(
      body: Builder(
        builder: (context) => Stack(
          fit: StackFit.expand,
          children: <Widget>[
            Container(
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              child: Image.asset('assets/landing.webp',
                  fit: BoxFit.fill,
                  color: Color.fromRGBO(255, 255, 255, 0.6),
                  colorBlendMode: BlendMode.modulate),
            ),
            Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                SizedBox(height: 10.0),
                Container(
                  width: 130.0,
                  child: Align(
                      alignment: Alignment.center,
                      child: RaisedButton(
                          shape: RoundedRectangleBorder(
                              borderRadius: new BorderRadius.circular(30.0)),
                          color: Color(0xffffffff),
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: <Widget>[
                              Icon(
                                FontAwesomeIcons.microsoft,
                                color: Color(0xFF01A6F0),
                              ),
                              // Visibility(
                              //   visible: !isSignedIn,
                              SizedBox(width: 10.0),
                              Text(
                                'Sign in',
                                style: TextStyle(
                                    color: Colors.black, fontSize: 18.0),
                              ),
                              // child: RaisedButton(
                              //   child: Text("Sign In"),
                              //   onPressed: handleSignIn,
                              // ),
                              // ),
                            ],
                          ),
                          onPressed: () => {                         
                            progressDialog.show(),
                                handleSignIn(),
                                progressDialog.hide()
                              })),
                )
              ],
            ),
          ],
        ),
      ),
    ));
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    只有在登录成功的情况下才应该导航到主页

    因为 Naviagation.Pop 等于返回按钮,用户可以手动操作

    这是一个更好的方法:

    在 main.dart 中添加:

      routes: {
          Homepage and being controled by PagesProvider 
    
            'nav': (context) => NavScreen(),
            'home': (context) => HomePage(),
             // add all routes with names here 
          },
    

    在您的 refreshSignedInStatus() 中:

    删除这个:

    Navigator.of(context).pop();
            Navigator.of(context).pushReplacement(
              MaterialPageRoute(
                builder: (context) => NavScreen(),
              ),
            );
    

    添加这个:

      Navigator.pushNamed(context, 'nav');
    

    【讨论】:

    • 在哪里添加登录按钮?
    • 这取决于 .. 如果您想制作仅限登录用户的应用体验,那么登录页面应该是新用户在打开应用时看到的第一件事 .. 但您正在尝试使其成为可选,然后您可以在顶部或侧面菜单中添加登录按钮以重定向到登录页面..并且您应该更改应用程序的逻辑和用户界面以根据用户登录状态进行更改
    • 登录屏幕是用户在启动应用程序时看到的第一件事,我的问题是,当您在主页上定义路由时,何时调用 home 和 login 的路由?因为按照你的方式做之后我得到了一个错误Could not find a generator for route RouteSettings("/", null) in the _WidgetsAppState.
    • 您没有在主页中定义路由,而是在 main.dart 中定义它,在调用主页之前返回 Material App .. 这是代码的完整示例:return MaterialApp( debugShowCheckedModeBanner: false, routes: { 'splash': (context) => SplashScreen(), 'home': (context) => HomePage(), }, home: SplashScreen(), );
    • 我分享了我的 Main.dart 代码,这给了我错误,它可以找出去哪里
    猜你喜欢
    • 2019-04-11
    • 2020-06-05
    • 1970-01-01
    • 2020-11-24
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 2020-04-22
    相关资源
    最近更新 更多