需要 Flutter 帮助 - “发生异常。构建期间调用 FlutterError(setState() 或 markNeedsBuild()...”

问题描述 投票:0回答:1

我正在尝试构建一个 Flutter 应用程序,但我一直在尝试动态更新列表中项目的数量。我正在从本地读取 json 文件,然后将其保存到 MyAppState 中的列表中。然后该列表将在 gridview 中显示给用户。列表中的每个项目都有一个加号和减号按钮,我可以使用 onPressed() 从用户的项目“集合”中添加/删除项目。我目前面临的问题是每个项目汇总所有项目的数量,而不是独立显示每个项目的数量。我希望我能让这个应用程序正确显示每个值。任何帮助将不胜感激。谢谢!

Adding 6 of the first card Adding 1 of the last card

这是我收到的主要错误:

"Exception has occurred.
FlutterError (setState() or markNeedsBuild() called during build.
This \_InheritedProviderScope\<MyAppState?\> widget cannot be marked as needing to build because the framework is already in the process of building widgets. 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:
\_InheritedProviderScope\<MyAppState?\>
The widget which was currently being built when the offending call was made was:
MediaQuery)".

这是我的代码:


class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => MyAppState(),
      child: MaterialApp(
        title: 'Stash Box',
        theme: ThemeData(
          useMaterial3: true,
          colorScheme: ColorScheme.fromSeed(seedColor: Colors.white),
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyAppState extends ChangeNotifier {
  var current = WordPair.random();

  var favorites = <WordPair>[];

  var collection = <String>[]; 

  void collectionAdd(String card){
    collection.add(card);
    notifyListeners();
  }

  int count(String card){
      int count = 0;
    for(var item in collection){
      if(collection.contains(card)){
        count++;
      }
        
    }
    //notifyListeners();
    return count;
  }

    void collectionRemove(String card){
      if(collection.contains(card)){
        collection.remove(card);
      }
    //collection.add(card);
    notifyListeners();
  }


  void toggleFavorite() {
    if (favorites.contains(current)) {
      favorites.remove(current);
    } else {
      favorites.add(current);
    }
    notifyListeners();
  }
}

class SpiritsCollectionPage extends StatefulWidget {
  const SpiritsCollectionPage({super.key});

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

class __SpiritsCollectionState extends State<SpiritsCollectionPage> {
  List _cards = [];

  Future<void> readJson() async {
    final String response = await rootBundle.loadString('assets/spirits2.json');
    final data = await json.decode(response);
    //int len = data.length;
    //_cards[len];
    setState(() {
      _cards = data['cards'];
    });
  }

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) async {
      await readJson();
    });
  }

  @override
  Widget build(BuildContext context) {
     var appState = context.watch<MyAppState>();
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () {
            // Navigate back to the previous screen by popping the current route
            Navigator.of(context).pushReplacement(MaterialPageRoute(
                    builder: (_) => CollectionsPage(),
                     ));
          },
        ),
        centerTitle: true,
        title: const Text(
          "High Spirits Collection",
        ),
      ),
      body: GridView.builder(
        itemCount: _cards.length,

        itemBuilder: (BuildContext context, int index) {
          return SizedBox(
              height: 150,
              child: FullScreenWidget(
                disposeLevel: DisposeLevel.Medium,
                child: Column(
                  
                  children: [
                    ClipRRect(
                      borderRadius: BorderRadius.circular(2), // Image border
                      child: SizedBox.fromSize(
                        size: Size.square(135), // Image radius
                        child: Image.asset(_cards[index]["photo"]),
                        
                      ),
                    ),
                    Center(
                      child: Row(
                        
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          TextButton(
                            
                                style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red)),
                                child: const Text(
                                  '-1',
                                  style: TextStyle(
                                    color: Colors.white,
                                    //decoration: TextDecoration.underline,
                                    decorationColor: Color.fromARGB(255, 0, 0, 0),
                                    decorationStyle: TextDecorationStyle.wavy,
                                  ),
                                ),
                                onPressed: () {
                                 appState.collectionRemove(_cards[index].toString());
                                },
                              ),
                              SizedBox(

                                width: 50,
                                child: Center(child: Text('${appState.count(_cards[index].toString())}'))),
                              TextButton(
                                style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.blue)),
                                child: const Text(
                                  '+1',
                                  style: TextStyle(
                                    color: Color.fromARGB(255, 255, 255, 255),
                                    decoration: TextDecoration.underline,
                                    decorationColor: Colors.blue,
                                    decorationStyle: TextDecorationStyle.wavy,
                                  ),
                                ),
                                onPressed: () {
                                 appState.collectionAdd(_cards[index].toString());
                                },
                              ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
             );
        },

        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount:2,
          mainAxisSpacing: 16,
          
        ),
        //padding: EdgeInsets.all(16),

        scrollDirection: Axis.vertical,

        // onTap:
      ),
    );
  }
}
flutter flutter-dependencies
1个回答
0
投票

尝试使用

FutureBuilder
加载 readJson 而不是 InitState。

删除:

WidgetsBinding.instance.addPostFrameCallback((_) async {
      await readJson();
    });

用这个 FutureBuilder 包装你的小部件:

FutureBuilder(
          future: readJson(),
    ...
© www.soinside.com 2019 - 2024. All rights reserved.