Проверка состояния задержки внутри слушателя блока Flutter

Я отправляю данные на сервер через блок и показываю progressSnackBar во время, а затем successSnackBar в случае успеха. Иногда это занимает меньше секунды, и имеет смысл вообще не отображать progressSnackBar - другими словами, подождите секунду, а затем проверьте, остается ли состояние UpdatingAccount. Я пробовал и потерпел неудачу с различными комбинациями, включающими Future.delay(...), и я, вероятно, смогу взломать setState, но есть ли способ добиться этого только внутри слушателя блока?

BlocListener<AccountBloc, AccountState>(
  listener: (BuildContext context, state) {
    if (state is UpdatingAccount) { // <-- delay this
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(progressSnackBar());
    } else if (state is AccountUpdated) {
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(successSnackBar());
    }
  },
  // rest...
),

person galki    schedule 02.12.2019    source источник
comment
Не могли бы вы вместо этого поместить логику ожидания в 1 секунду в свой BLOC? Вы можете дважды передать UpdatingAccount и указать прошедшее время, чтобы ваш слушатель мог решить, следует ли показывать прогресс. Затем просто опустите второй выход, если процесс выполняется менее чем за 1 секунду. Или такое управление потоком внутри BLOC считается плохой практикой? Я все еще новичок в этом шаблоне.   -  person Jason Tyler    schedule 29.01.2020


Ответы (2)


В итоге я сделал виджет с отслеживанием состояния и дал ему член _updated bool.

BlocListener<AccountBloc, AccountState>(
  listener: (BuildContext context, state) {
    if (state is UpdatingAccount) {
      _updated = false;
      Future.delayed(Duration(seconds: 1), () {
        if (!_updated) {
          Scaffold.of(context)
            ..hideCurrentSnackBar()
            ..showSnackBar(progressSnackBar());
        }
      });
    } else if (state is AccountUpdated) {
      _updated = true;
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(successSnackBar());
    }
  },
  // rest...
),
person galki    schedule 03.12.2019

Вы можете выполнить Future.delay() в своем state is UpdatingAccount состоянии и снова проверить состояние.

if (state is UpdatingAccount) { 
  Future.delayed(Duration(seconds: 1), (){
    if(state is "UpdatingAccount"){
      Scaffold.of(context)
        ..hideCurrentSnackBar()
        ..showSnackBar(progressSnackBar());
    }
  });
}
person dubace    schedule 02.12.2019
comment
Как я уже упоминал, Future.delay()ing не работает. - person galki; 03.12.2019