BLoC: прослушивание обратного вызова, вызываемого несколько раз - PullRequest
0 голосов
/ 10 июня 2019

У меня есть Stateful Widget, который получает блок от своего родителя:

class Page extends StatefulWidget {
  @override
  State<StatefulWidget> createState() =>
  _PageState();
}

class _PageState extends State<Page> {
  final TextEditingController mnemonicController = TextEditingController();
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {

final MnemonicLogicBloc mnemonicLogicBloc =
BlocProvider.of<MnemonicLogicBloc>(context);

mnemonicLogicBloc.outCheckMnemonic.listen((isCorrect){
  if (!isCorrect) {
    SnackBar copySnack = SnackBar(content: Text('Wrong Mnemonic!'));
    _scaffoldKey.currentState.showSnackBar(copySnack);
  }
});

return Scaffold(
    key: _scaffoldKey,
    body: Container(
      width: double.infinity,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Container(
            child: TextField(
              controller: mnemonicController,
            ),
          ),
          RaisedButton(
            onPressed: () {
              mnemonicLogicBloc.isMnemonicCorrect(mnemonicController.text);
            },
            child: Text('Check', style: TextStyle(color: Colors.white)),
          )
        ],
      ),
    ));
}
}

Что я хочу сделать, это проверить, когда пользователь нажимает кнопку, правильность введенной строки. Метод, который я вызываю в блоке:

void isMnemonicCorrect(String typedMnemonic){
if(typedMnemonic == _lastGeneratedMnemonic)
  _inCheckMnemonic.add(true);
else
  _inCheckMnemonic.add(false);
 }

_inCheckMnemonic - это мойка моего предмета (я использую rxDart), а outCheckMnemonic - мой поток. Проблема в том, что, хотя метод isCorrect блока вызывается один раз, обратный вызов listen вызывается дважды (SnackBar отображается дважды). Почему это происходит?

РЕДАКТИРОВАТЬ: я перехожу к странице (), просто используя Navigator.push:

Navigator.of(context).push(MaterialPageRoute(
                            builder: (BuildContext context) {
                return Page();
}));

Я могу получить блок, потому что при запуске приложения я инициализировал блок:

return runApp(BlocProvider<ApplicationBloc>(
bloc: ApplicationBloc(),
child: BlocProvider<MnemonicLogicBloc>(
  bloc: MnemonicLogicBloc(),
  child: BlocProvider<HomePageBloc>(
    bloc: HomePageBloc(),
    child: App(),
  ),
)

));

1 Ответ

2 голосов
/ 10 июня 2019

Когда вы добавляете новый Widget в свой Navigator, избегайте создания этого виджета внутри компоновщика, вместо этого объявляйте переменную снаружи и повторно используйте эту переменную в компоновщике, например:

final page = Page();
Navigator.of(context).push(MaterialPageRoute(
                            builder: (BuildContext context) => page ), );

СЭто изменение позволяет избежать непредвиденного повторного создания нашего виджета много раз.

...