首页 > 解决方案 > Flutter/Dart 应用程序在构建小部件时抛出异常

问题描述

所以我一直在看一个 youtube 教程,用于在 dart/flutter 中制作日历应用程序。不过,视频中编写的代码似乎对我不起作用。它与构建其中一个小部件有关,但我没有编写这个特定的代码,也没有在 dart 或 Flutter 方面的丰富经验。这是错误消息。

I/flutter (10952): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (10952): The following assertion was thrown building HomePage(dirty, dependencies:
I/flutter (10952): [_LocalizationsScope-[GlobalKey#2a61b], _InheritedTheme], state: _HomePageState#6701d):
I/flutter (10952): setState() or markNeedsBuild() called during build.
I/flutter (10952): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter (10952): process of building widgets.  A widget can be marked as needing to be built during the build phase
I/flutter (10952): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter (10952): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter (10952): Otherwise, the framework might not visit this widget during this build phase.
I/flutter (10952): The widget on which setState() or markNeedsBuild() was called was:
I/flutter (10952):   Overlay-[LabeledGlobalKey<OverlayState>#6d6f2]
I/flutter (10952): The widget which was currently being built when the offending call was made was:
I/flutter (10952):   HomePage
I/flutter (10952):
I/flutter (10952): The relevant error-causing widget was:
I/flutter (10952):   HomePage 
package:hello_world/main.dart:15
I/flutter (10952):
I/flutter (10952): When the exception was thrown, this was the stack:
I/flutter (10952): #0      Element.markNeedsBuild.<anonymous closure> 
package:flutter/…/widgets/framework.dart:3896
I/flutter (10952): #1      Element.markNeedsBuild 
package:flutter/…/widgets/framework.dart:3911
I/flutter (10952): #2      State.setState 
package:flutter/…/widgets/framework.dart:1168
I/flutter (10952): #3      OverlayState.insertAll 
package:flutter/…/widgets/overlay.dart:344
I/flutter (10952): #4      OverlayRoute.install 
package:flutter/…/widgets/routes.dart:44
I/flutter (10952): #5      TransitionRoute.install 
package:flutter/…/widgets/routes.dart:181
I/flutter (10952): #6      ModalRoute.install 
package:flutter/…/widgets/routes.dart:959
I/flutter (10952): #7      NavigatorState.push 
package:flutter/…/widgets/navigator.dart:1791
I/flutter (10952): #8      showGeneralDialog 
package:flutter/…/widgets/routes.dart:1634
I/flutter (10952): #9      showDialog 
package:flutter/…/material/dialog.dart:711
I/flutter (10952): #10     _HomePageState._showAddDialog

这是代码本身:

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:table_calendar/table_calendar.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Calendar',
      theme: ThemeData(
        primarySwatch: Colors.grey, 
      ),
    home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  CalendarController _controller;
  Map<DateTime,List<dynamic>> _events;
  TextEditingController _eventController;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller = CalendarController();
    _eventController = TextEditingController();
    _events = {};
  }

Map<String, dynamic> encodeMap(Map<DateTime, dynamic> map) {
    Map<String, dynamic> newMap = {};
    map.forEach((key, value) {
      newMap[key.toString()] = map[key];
    });
    return newMap;
  }

Map<DateTime, dynamic> decodeMap(Map<String, dynamic> map) {
  Map<DateTime, dynamic> newMap = {};
  map.forEach((key, value) {
    newMap[DateTime.parse(key)] = map[key];
  });
  return newMap;
}


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flutter Calendar'),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            TableCalendar(
              events: _events,
              initialCalendarFormat: CalendarFormat.month,
              calendarStyle: CalendarStyle(
                todayColor: Colors.blue,
                selectedColor: Theme.of(context).primaryColor,
                todayStyle: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 18.0,
                  color: Colors.white
                )
              ),
              calendarController: _controller,
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: _showAddDialog(),
      ),
    );
  }

  _showAddDialog(){
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        content: TextField(
            controller: _eventController,
          ),
          actions: <Widget>[
            FlatButton(
              child: Text("Save"),
              onPressed: (){
                if(_eventController.text.isEmpty) return;
                setState(() {
                  if(_events[_controller.selectedDay] != null){
                  _events[_controller.selectedDay].add
                  (_eventController.text);
                  }else{
                    _events[_controller.selectedDay] = [_eventController.text];
                  }
                });
              },
            )
          ]
      )
    );
  }
}

标签: androidflutterdart

解决方案


你能改变这个吗

 floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: _showAddDialog(),
 ),

 floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: _showAddDialog,
 ),

当您编写时_showAddDialog(),您会调用该方法本身,因此您正在调用setState()此方法。


推荐阅读