Flutter:在构建错误期间调用了 setState() 或 markNeedsBuild()

Posted

技术标签:

【中文标题】Flutter:在构建错误期间调用了 setState() 或 markNeedsBuild()【英文标题】:Flutter: setState() or markNeedsBuild() called during build error 【发布时间】:2021-09-09 13:05:12 【问题描述】:

我正在开发一个颤振应用程序。请检查以下代码。

LoadingScreen2

class LoadingScreen2 extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: _LoadingScreen2UI(),
    );
  


class _LoadingScreen2UI extends StatefulWidget 
  @override
  State<StatefulWidget> createState() 
    return _LoadingScreen2UIState();
  


class _LoadingScreen2UIState extends State<_LoadingScreen2UI> 
  @override
  Widget build(BuildContext context) 
    return SafeArea(
      child: Scaffold(
        body: LayoutBuilder(builder: (context, constraints) 
          final maxHeight = constraints.maxHeight;
          return SingleChildScrollView(
            physics: BouncingScrollPhysics(),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                SizedBox(height: maxHeight * 0.1),
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  child: Text(
                      "This is a Text",
                      style: heading1Style),
                ),
                SizedBox(height: maxHeight * 0.04),
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 16),
                  child: Text(
                      "This is another text",
                      style: fadedSubtitle1Style),
                ),
                SizedBox(height: maxHeight * 0.04),
                Image.asset("assets/graphics/splash.png")
              ],
            ),
          );
        ),
      ),
    );
  

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

    initProcess();
  

  void initProcess() async 
    LoadingScreen2Controller _loadingController = LoadingScreen2Controller();
    await _loadingController.initProcess(context);
  

LoadingScreen2Controller

class LoadingScreen2Controller 
  ///
  /// Process the starting work load of the loading screen
  Future<void> initProcess(BuildContext context) async 
    final FirebaseAuthService firebaseAuthService =
        Provider.of<FirebaseAuthService>(context, listen: false);
    final UserService userService =
        Provider.of<UserService>(context, listen: false);
    final UserRoleService userRoleService =
        Provider.of<UserRoleService>(context, listen: false);
    final RoleService roleService =
        Provider.of<RoleService>(context, listen: false);

    // check whether the user is logged in
    fireauth.User? user = firebaseAuthService.getUser();

    if (user == null) 
      print("User eror: ");
      Navigator.of(context)
          .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
     else 
      // if the user is logged in, load the initial data and send him to the home screen
      String authToken = await firebaseAuthService.getUser()!.getIdToken();
      await roleService.getAllRoles(authToken);

      Navigator.of(context)
          .pushNamedAndRemoveUntil('/home', (Route<dynamic> route) => false);
    
  

您可以在我的LoadingScreen2 中看到我正在运行initState,它调用控制器类,控制器类将在其中获取一些数据并导航到另一个屏幕。

但是当它导航时,我收到以下错误。没有崩溃,但会产生错误。

E/flutter (27631): #1      _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)


E/flutter (27631): #2      _RouteEntry.handlePush.<anonymous closure>
package:flutter/…/widgets/navigator.dart:3018

E/flutter (27631): #3      TickerFuture.whenCompleteOrCancel.thunk
package:flutter/…/scheduler/ticker.dart:407

E/flutter (27631): #4      _rootRunUnary (dart:async/zone.dart:1362:47)


E/flutter (27631): #5      _CustomZone.runUnary (dart:async/zone.dart:1265:19)


E/flutter (27631): <asynchronous suspension>


E/flutter (27631): #6      TickerFuture.whenCompleteOrCancel.thunk (package:flutter/src/scheduler/ticker.dart)
package:flutter/…/scheduler/ticker.dart:1

E/flutter (27631): <asynchronous suspension>


E/flutter (27631):


W/libEGL  (27631): EGLNativeWindowType 0x7347f0e010 disconnect failed


W/libEGL  (27631): EGLNativeWindowType 0x73a765a950 disconnect failed


D/ZrHung.AppEyeUiProbe(27631): not watching, wait.

我该如何解决这个问题?

【问题讨论】:

initState 没有context。当您在 initProcess() 上使用上下文时。您可以按照@Sameera Perera 的回答,如果您仍然面临使用FutureBuilder 的任何尝试,它可能会解决问题,希望此小部件不需要它。 【参考方案1】:

尝试像这样调用initProcess方法。

@override
void initState() 
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) 
        initProcess();
    );

【讨论】:

以上是关于Flutter:在构建错误期间调用了 setState() 或 markNeedsBuild()的主要内容,如果未能解决你的问题,请参考以下文章

Flutter:在构建期间调用 setState() 或 markNeedsBuild()

如何修复 Flutter 构建问题期间调用的 setState

Flutter :setState() 或 markNeedsBuild() 在构建期间调用

在构建期间调用 setState() 或 markNeedsBuild() - Flutter

Flutter - 在构建期间调用 setState() 或 markNeedsBuild()

Flutter VideoPlayerController “在构建期间调用了 setState() 或 markNeedsBuild()。”