OverlayEntry.remove() не удаляет запись из overlayState

#dart #flutter #overlay

#dart #флаттер #наложение

Вопрос:

Я пишу приложение flutter, используя Flutter 1.2.1.

внутри initState() моего StatefulWidget я вызываю showOverlay() функцию, которую я создал со следующим кодом:

  void showOverlay(BuildContext context) async {
    final OverlayState overlayState = Overlay.of(context);
    final OverlayEntry overlayEntry = OverlayEntry(
      builder: (BuildContext context)=>Positioned(
        left: 0.0,
        right: 0,
        bottom: 90.0,
        child: Container(
            margin: const EdgeInsets.all(15.0),
            padding: const EdgeInsets.all(3.0),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(25.0),
                border: Border.all(color: Colors.blueAccent)
            ),
          child:
                Text('Focus, lighting and contrast help',style: TextStyle(fontWeight: FontWeight.normal,
                    color: Colors.white,
                    fontSize: 18.0,
                    decoration: TextDecoration.none)),

          )
        ),
    );
    overlayState.insert(overlayEntry);
    await Future<dynamic>.delayed(Duration(seconds: 2));
    overlayEntry.remove();

  }
  

проблема в том, что после задержки в 2 секунды наложение все еще отображается на экране.

что я упускаю?

Спасибо

Комментарии:

1. @pskink — из прошлых сеансов ?! интересно.. я изучу это. Спасибо

Ответ №1:

когда я отлаживал, я заметил следующее предупреждение:

 This Overlay 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.
  

Я погуглил и нашел эту проблему:
https://github.com/flutter/flutter/issues/21638

поэтому, чтобы решить эту проблему, я изменил

 overlayState.insert(overlayEntry);
  

к этому:

 WidgetsBinding.instance.addPostFrameCallback((_) => overlayState.insert(overlayEntry));
  

Комментарии:

1. Отличная проблема решена, спасибо за ваш ответ!

Ответ №2:

Для тех, кому все еще нужно решение после попытки использования предложенных выше. Мне потребовалось несколько часов, чтобы найти проблему. Если в вашем коде происходит вставка объекта overlay entry несколько раз, нет рабочего способа удалить его. Например, случайное выполнение этого кода для вставки overlay несколько раз:

 overlayEntry = _overlayEntryBuilder();
Overlay.of(context).insert(overlayEntry));
  

Затем пытается удалить:

   overlayEntry?.remove();
  overlayEntry = null;
  

Удаление работает, только если вы вызвали

 Overlay.of(context).insert(overlayEntry)); 
  

один раз. Вероятно, он создает несколько экземпляров, если вы вызовете его несколько раз, и remove не сработает, он останется активным в вашем приложении. Вы можете легко столкнуться с этой ситуацией, если используете триггеры OnChanged или .listen ненадлежащим образом.