Приложение Flutter / Dart вызывает исключение при создании виджета - PullRequest
1 голос
/ 01 мая 2020

Итак, я смотрел учебник YouTube по созданию приложения-календаря в дартс / флаттер. Код, который написан на видео, похоже, не работает для меня. Это как-то связано с созданием одного из виджетов, но я не писал этот конкретный код или не имел большого опыта работы с дротиками или трепетанием. Вот сообщение об ошибке.

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];
                  }
                });
              },
            )
          ]
      )
    );
  }
}

1 Ответ

2 голосов
/ 01 мая 2020

Не могли бы вы изменить это

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

на

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

Когда вы пишете _showAddDialog(), вы вызываете там сам метод, поэтому вы вызываете setState() в этом способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...