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

Я делаю приложение календаря / планировщика для android, используя Dart / Flutter. Приложение отлично работает при первом запуске, но если я закрою приложение в эмуляторе и снова открою, оно выдаст ошибку. Однако приложение снова начнет работать, если я перезапущу его с помощью функций запуска / отладки в коде Visual Studio. Также, если для устранения неполадок требуется больше стека, просто ответьте в комментариях, и я выложу все, что нужно.

Мой код выглядит следующим образом:

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.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.blue,
      ),
      home: HomePage(),
    );
  }
}

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

class _HomePageState extends State<HomePage> {
  CalendarController _controller;
  Map<DateTime, List<dynamic>> _events;
  List<dynamic> _selectedEvents;
  TextEditingController _eventController;
  SharedPreferences prefs;

  @override
  void initState() {
    super.initState();
    _controller = CalendarController();
    _eventController = TextEditingController();
    _events = {};
    _selectedEvents = [];
    initPrefs();
  }

  initPrefs() async {
    prefs = await SharedPreferences.getInstance();
    setState(() {
      _events = Map<DateTime, List<dynamic>>.from(
        decodeMap(json.decode(prefs.getString("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.week,
              calendarStyle: CalendarStyle(
                canEventMarkersOverflow: true,
                todayColor: Colors.orange,
                selectedColor: Theme.of(context).primaryColor,
                todayStyle: TextStyle(
                  fontWeight: FontWeight.bold,
                  fontSize: 18.0,
                  color: Colors.white
                )
              ),
              headerStyle: HeaderStyle(
                centerHeaderTitle: true,
                formatButtonDecoration: BoxDecoration(
                  color: Colors.orange,
                  borderRadius: BorderRadius.circular(20.0),
                ),
                formatButtonTextStyle: TextStyle(color: Colors.white),
                formatButtonShowsNext: false,
              ),
              startingDayOfWeek: StartingDayOfWeek.sunday,
              onDaySelected: (date, events) {
                setState(() {
                  _selectedEvents = events;
                });
              },
              builders: CalendarBuilders(
                selectedDayBuilder: (context, date, events) => Container(
                  margin: const EdgeInsets.all(4.0),
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Theme.of(context).primaryColor,
                    borderRadius: BorderRadius.circular(10.0)
                  ),
                  child: Text(
                    date.day.toString(),
                    style: TextStyle(color: Colors.white),
                  )
                ),
                todayDayBuilder: (context, date, events) => Container(
                  margin: const EdgeInsets.all(4.0),
                  alignment: Alignment.center,
                  decoration: BoxDecoration(
                    color: Colors.orange,
                    borderRadius: BorderRadius.circular(10.0)
                  ),
                  child: Text(
                    date.day.toString(),
                    style: TextStyle(color: Colors.white),
                  )
                ),
              ),
              calendarController: _controller,
            ),

            ..._selectedEvents.map((event) => ListTile(
                  title: Text(event),
                )),

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

  _showAddDialog() async {
    await showDialog(
        context: context,
        builder: (context) => AlertDialog(
              content: TextField(
                controller: _eventController,
              ),
              actions: <Widget>[
                FlatButton(
                  child: Text("Save"),
                  onPressed: () {
                    if (_eventController.text.isEmpty) return;
                    if (_events[_controller.selectedDay] != null) {
                      _events[_controller.selectedDay].add(_eventController.text);
                    } else {
                      _events[_controller.selectedDay] = [
                        _eventController.text
                      ];
                    }
                    prefs.setString("events", json.encode(encodeMap(_events)));
                    _eventController.clear();
                    Navigator.pop(context);
                  },
                )
              ],
        )
      );
    setState(() {
      _selectedEvents = _events[_controller.selectedDay];
    });
  }
}

и сообщение об ошибке, которое я получаю, когда Я закрываю приложение и заново открываю его в эмуляторе так:

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

1 Ответ

0 голосов
/ 03 мая 2020

Эта проблема была исправлена ​​путем удаления самого приложения в эмуляторе, поскольку существовала «странная проблема с кешем», которая вызывала некоторый старый код, который вызывал эту ошибку, вызывая сбои при закрытии и перезапуске приложения в самом эмуляторе.

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