Есть ли подходящая замена WillPopScope, а не PopScope?

Я создал приложение для чата, но у меня возникают проблемы с его экраном чата, потому что я использую пакет emoji_picker_flutte для отображения доски смайлов, и я реализовал его так, что всякий раз, когда доска смайлов была на логической переменной, это было true, и наоборот, и если пользователь сначала использует жест обратной навигации, доска смайлов исчезнет, ​​а затем, если пользователь снова использует жест обратной навигации, страница всплывет.

При использовании WillPopScope проблем не было, но в последнее время с PopScope их нет. Я попытался поместить весь код в onPopInvoked, как было сказано при миграции, с canPop, установленным на false, но это не работает. Я также попытался использовать весь код в отдельной функции с типом возвращаемого значения как bool и использовать эту функцию на canPop, но это не удалось, потому что canPop работает все время, пока эта страница включена, при использовании таким образом доска смайлов даже не появляется и потому что при нажатии кнопки эмодзи и повороте переменной true она сразу становится false, при этом все работает нормально.

bool _willpop() {
    if (_showEmoji) {
      setState(() => _showEmoji = !_showEmoji);
      return false;
    } else {
      return true;
    }
  }


PopScope (
canPop = _willpop();
child:...
)

Другой путь

_willpop(bool p) {
    if (p) return;
    if (_showEmoji) {
      change();
      return false;
    } else {
      return true;
    }
  }

PopScope (
canPop: false,
onPopInvoked: (didpop) => _willpop(didpop),
child:...
)

оба способа не работают, может кто-нибудь предложить лучший способ для этого

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
73
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Во втором случае, если p истинно, ничего не возвращайте. Просто удалите эту строку.

if (p) return;

Теперь, если _showEmoji имеет значение true, просто измените его значение и вызовите setState, но если оно ложно, используйте Navigator.pop(context) для всплывающего окна.

_willpop(bool p) {
    if (_showEmoji) {
      change();
    } else {
      Navigator.pop(context);
    }
  }

Причина, по которой ваш первый метод не работает, может заключаться в том, что когда вы установили _showEmoji=true, вы не вызвали setState(), поэтому новый виджет PopScope не был создан с canPop как false, но все равно как true, что позволяет пользователю вернуться назад.

Но я советую не использовать первый метод, потому что этот метод вызывается при сборке виджета, и вы вызываете setState() при сборке виджета, который снова перестраивает виджет, если условие соответствует. Если условия не обрабатываются должным образом, виджет будет перестраиваться снова и снова.

Вот почему используйте второй метод, который вызывается только тогда, когда пользователь действительно пытается вернуться, а не при сборке виджета.

Итак, мне следует использовать второй метод без setState onPopInvoked? bool _willpop() { if (_showEmoji) { _showEmoji = !_showEmoji; вернуть ложь; } Еще {вернуть истину; } }

Vinayak Hinduja 11.04.2024 11:45

Вы можете использовать второй метод с установленным состоянием. В своем ответе я сказал не использовать его для первого метода. Когда вы вызываете setState внутри fn, который передается canPop и выполняется каждый раз при построении виджета. Но onPopInvoked — это обратный вызов fn, на который не влияет сборка виджета, он похож на кнопку. Вот почему сказано использовать второй метод. И хорошо, что вы нашли решение.

Ultranmus 11.04.2024 19:52
Ответ принят как подходящий

Я нашел решение, вот решение, и оно работает так, как я хотел

  bool _showEmoji = false;

  void change() => setState(() => _showEmoji = !_showEmoji);

  _willpop() {
   if (_showEmoji) change(); 
  }

  PopScope(
  canPop: !_showEmoji,
  onPopInvoked: (_) => _willpop(),
  child:...,
  ),

onPopInvoked запросил void fn. Так что ничего возвращать не нужно было. _willpop() должен быть пустым fn.

Ultranmus 11.04.2024 19:49

Благодарим вас за вклад в сообщество Stack Overflow. Возможно, это правильный ответ, но было бы очень полезно предоставить дополнительные пояснения к вашему коду, чтобы разработчики могли понять ваши рассуждения. Это особенно полезно для новых разработчиков, которые не так хорошо знакомы с синтаксисом или пытаются понять концепции. Не могли бы вы отредактировать свой ответ, включив в него дополнительную информацию на благо сообщества?

Jeremy Caney 12.04.2024 03:25

да, я обновил его сейчас, прежде чем использовать тот же код, что и в Willpopscope.

Vinayak Hinduja 13.04.2024 15:57

Другие вопросы по теме