简体   繁体   English

“在构建过程中调用了 setState() 或 markNeedsBuild()”如何解决这个问题?

[英]"setState() or markNeedsBuild() called during build" how to resolve this?

Here is the full error message.这是完整的错误消息。

The following assertion was thrown building MealDeatialRoute(dirty, dependencies: [MediaQuery, _ModalScopeStatus]): setState() or markNeedsBuild() called during build.构建 MealDeatialRoute(dirty, dependencies: [MediaQuery, _ModalScopeStatus]) 时引发了以下断言:setState() 或 markNeedsBuild() 在构建期间调用。

This MyApp widget cannot be marked as needing to build because the framework is already in the process of building widgets.此 MyApp 小部件无法标记为需要构建,因为框架已经在构建小部件的过程中。 A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building.仅当其祖先之一当前正在构建时,才可以在构建阶段将小部件标记为需要构建。 This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built.这个例外是允许的,因为框架在子部件之前构建父部件,这意味着总是会构建一个脏的后代部件。 Otherwise, the framework might not visit this widget during this build phase.否则,框架可能不会在此构建阶段访问此小部件。 The widget on which setState() or markNeedsBuild() was called was: MyApp调用 setState() 或 markNeedsBuild() 的小部件是:MyApp

And Here is a code of main.这是main 的代码。

import 'package:flutter/material.dart';

import './routes/main_tab_route.dart';
// import './routes/favorites_tab_route.dart';
// import './routes/filter_tab_route.dart';
import './routes/category_meal_route.dart';
import './routes/meal_detial_route.dart';
import './routes/select_filter_route.dart';

import './dummy_data.dart';
import './model/meal.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var _filters = {
    'gluteenFree': false,
    'lactoseFree': false,
    'vegan': false,
    'vegetarian': false,
  };

  final List<Meal> _avialableMeal = dummyMeals;

  final List<Meal> _favoriteMeal = [];

  void _toggleFavorite(String id) {
    int existIndex = _favoriteMeal.indexWhere((meal) => meal.id == id);

    if (existIndex >= 0) {
      setState(() {
        _favoriteMeal.removeAt(existIndex);
      });
    } else {
      setState(() {
        _favoriteMeal.add(dummyMeals.firstWhere((meal) => meal.id == id));
      });
    }
  }

  bool _isMealFavorite(String id) {
    return _favoriteMeal.any((meal) => meal.id == id);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Meal App',
      theme: ThemeData(
        primaryColor: Colors.red,
        colorScheme:
            ColorScheme.fromSwatch().copyWith(secondary: Colors.amberAccent),
        appBarTheme: const AppBarTheme(
          titleTextStyle: TextStyle(
            fontSize: 23,
            fontWeight: FontWeight.bold,
          ),
        ),
        textTheme: const TextTheme(
          titleMedium: TextStyle(
            fontSize: 18,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => MainTabRoute(_favoriteMeal),
        SelectFilterRoute.routeName: (context) => SelectFilterRoute(),
        CategoreyMealRoute.routeName: (context) => CategoreyMealRoute(),
        MealDeatialRoute.routeName: (context) =>
            MealDeatialRoute(_toggleFavorite, _isMealFavorite),
      },
    );
  }
}

And an error is cause by MealDeatailRoute.dart file so which is below错误是由MealDeatailRoute.dart文件引起的,如下所示

import 'package:flutter/material.dart';
import 'package:mealapp/dummy_data.dart';

class MealDeatialRoute extends StatelessWidget {
  static const routeName = '/meal-detail';

  final Function toggleFavorite;
  final Function isFavorite;

  MealDeatialRoute(this.isFavorite, this.toggleFavorite);

  @override
  Widget build(BuildContext context) {
    final mealId = ModalRoute.of(context)!.settings.arguments as String;

    final meal = dummyMeals.firstWhere((meal) => meal.id == mealId);

    AppBar appBar = AppBar(
      title: Text(meal.title),
    );

    Widget _buildTitle(String title) {
      return Padding(
        padding: const EdgeInsets.all(10),
        child: Text(
          title,
          style: const TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.bold,
          ),
        ),
      );
    }

    Widget _buildContainer(Widget child) {
      return Container(
        margin: const EdgeInsets.symmetric(horizontal: 30, vertical: 10),
        height: 200,
        decoration: BoxDecoration(
          border: Border.all(color: Colors.black, width: 1),
        ),
        child: child,
      );
    }

    final mediaQuery = MediaQuery.of(context);

    final contentSize = mediaQuery.size.height -
        mediaQuery.padding.top -
        appBar.preferredSize.height;

    return Scaffold(
      appBar: appBar,
      body: Column(
        children: [
          Image.network(
            meal.imageUrl,
            fit: BoxFit.cover,
            height: contentSize * 0.4,
          ),
          SizedBox(
            height: contentSize * 0.6,
            child: SingleChildScrollView(
              child: Column(
                children: [
                  _buildTitle('Ingreidants'),
                  _buildContainer(ListView(
                    children: meal.ingredients
                        .map(
                          (inData) => Container(
                            margin: const EdgeInsets.all(10),
                            padding: const EdgeInsets.all(10),
                            decoration: BoxDecoration(
                                color: Colors.amber,
                                borderRadius: BorderRadius.circular(10)),
                            child: Text(inData),
                          ),
                        )
                        .toList(),
                  )),
                  _buildTitle('Steps'),
                  _buildContainer(
                    ListView.builder(
                      itemCount: meal.steps.length,
                      itemBuilder: ((context, index) {
                        return Column(
                          children: [
                            ListTile(
                              leading: CircleAvatar(
                                child: Text('# ${index + 1}'),
                              ),
                              subtitle: Text(meal.steps[index]),
                            ),
                            const Divider(),
                          ],
                        );
                      }),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          toggleFavorite(mealId);
        },
        child: Icon(
          // Icons.star,
          isFavorite(mealId) ? Icons.star : Icons.star_border,
        ),
      ),
    );
  }
}

I also find some this types of error on this site but I didn't figured it out why this happened so why this error showing?我也在这个网站上发现了一些这种类型的错误,但我没有弄明白为什么会这样,为什么会显示这个错误?

You are using positional constructurctor, this makes consfusion on MealDeatialRoute consturctor.您正在使用位置构造函数,这会混淆MealDeatialRoute构造函数。

You are reading like你正在阅读

MealDeatialRoute(this.isFavorite, this.toggleFavorite);

But on _AppState, passing on wrong order.但是在 _AppState 上,传递错误的顺序。

 MealDeatialRoute.routeName: (context) =>
            MealDeatialRoute(_toggleFavorite, _isMealFavorite),

Which will be这将是

MealDeatialRoute(_isMealFavorite, _toggleFavorite),

To avoid this error in the future, try using named constructor.为避免将来出现此错误,请尝试使用命名构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在构建 TextField 期间调用 setState() 或 markNeedsBuild() - setState() or markNeedsBuild() called during build TextField 无限滚动列表视图 - 在构建期间调用的setState()或markNeedsBuild - Infinite Scroll listview - setState() or markNeedsBuild called during build setState() 或 markNeedsBuild() 在构建期间调用。 在导航推送中 - setState() or markNeedsBuild() called during build. in Navigator Push flutter 应用程序中的“setState() 或 MarkNeedsBuild() 调用期间”错误 - “setState() or MarkNeedsBuild() called during” error in flutter app 如何将函数从子类传递到父类,我收到此错误:在构建期间调用了 setState() 或 markNeedsBuild() - How to pass function from a child class to parent class, I am getting this error: setState() or markNeedsBuild() called during build (在构建过程中出现错误)在构建过程中调用了 setState() 或 markNeedsBuild()。相关的导致错误的小部件是 MaterialApp - (Getting the error while building) setState() or markNeedsBuild() called during build.The relevant error-causing widget was MaterialApp Flutter:当小部件树被锁定时调用 setState() 或 markNeedsBuild() ... 在方向更改期间 - Flutter: setState() or markNeedsBuild() called when widget tree was locked... during orientation change 在ndk-build期间如何解决“通用ELF中的重定位”? - How to resolve “Relocations in Generic ELF” during ndk-build? setState()如何取决于调用哪个组件函数? - How to setState() depend on which component func is called? 如何解决构建路径错误? - How to resolve build path errors?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM