Вызов нижнего листа стойкости без setState (с использованием StreamBuilder)

#flutter

#flutter

Вопрос:

Я хочу достичь PersistentBottomSheet, но не хочу использовать setState() . хотите добиться throw StreamBuilder

Я попробовал приведенный ниже код с setState, он работает, но использовал StreamBuilder, он не дал ожидаемого результата

  VoidCallback _showBottomSheetCallback;

  @override
  void initState() {
    super.initState();
    _showBottomSheetCallback = _showBottomSheet;
  }

void _showBottomSheet() {
    setState(() { // disable the button
      _showBottomSheetCallback = null;
    });
    _scaffoldKey.currentState.showBottomSheet<void>((BuildContext context) {
      final ThemeData themeData = Theme.of(context);
      return Container(
        decoration: BoxDecoration(
          border: Border(top: BorderSide(color: themeData.disabledColor))
        ),
        child: Padding(
          padding: const EdgeInsets.all(32.0),
          child: Text('This is a Material persistent bottom sheet. Drag downwards to dismiss it.',
            textAlign: TextAlign.center,
            style: TextStyle(
              color: themeData.accentColor,
              fontSize: 24.0,
            ),
          ),
        ),
      );
    })
    .closed.whenComplete(() {
      if (mounted) {
        setState(() { // re-enable the button
          _showBottomSheetCallback = _showBottomSheet;
        });
      }
    });
  }
  

Он работает идеально, но как только я оборачиваю его внутри StreamBuilder, он не дает ожидаемого результата
Я создал поток, который будет принимать некоторые входные данные при нажатии поднятой кнопки, и он уведомит stream builder об этом, но это не сработает.
Внутри поднятой кнопки при нажатии у меня есть onPressed: _showBottomSheetCallback,

Ответ №1:

Я достигаю этого с помощью streams и stream builder следующим образом

создал контроллер потока и stream и функцию для добавления в stream в моем блочном классе как

 //controller
final _bottomSheetSubject = BehaviorSubject<String>();

//stream
Observable<String> get bottomSheetEvent => _bottomSheetSubject.stream;

//add value in a stream
Function(String) get addEventBottomSheet => _bottomSheetSubject.sink.add;
  

В моей части пользовательского интерфейса было сделано следующее

таким образом, исходными данными в моментальном снимке будет строка «show», и как только пользователь нажмет кнопку, данные, которые будут отправлены в поток, будут «нулевыми», на этот раз построитель потока будет вызван снова, поскольку он прослушивает поток, теперь данные, которые он сравнивает, и он вернет null для метода on press, и как только нижний лист будет закрыт, снова добавит «show» в поток, и снова в конечном итоге построитель потока вызовет данные как «show».

  Widget filterBtn() {
    return StreamBuilder(
      stream: homeBloc.bottomSheetEvent,
      initialData: 'show',
      builder: (BuildContext context, AsyncSnapshot<String> snapShot) {
        return RaisedButton(
          onPressed: () {
            if (snapShot.data == 'show') {
              homeBloc.addEventBottomSheet('null');
              _scaffoldKey.currentState
                  .showBottomSheet<void>((BuildContext context) {
                    final ThemeData themeData = Theme.of(context);
                    return Container(
                      decoration: BoxDecoration(
                          border: Border(
                              top: BorderSide(color: themeData.disabledColor))),
                      child: Padding(
                        padding: const EdgeInsets.all(32.0),
                        child: Text(
                          'This is a Material persistent bottom sheet. Drag downwards to dismiss it.',
                          textAlign: TextAlign.center,
                          style: TextStyle(
                            color: themeData.accentColor,
                            fontSize: 24.0,
                          ),
                        ),
                      ),
                    );
                  })
                  .closed
                  .whenComplete(() {
                    if (mounted) {
                      homeBloc.addEventBottomSheet('show');
                    }
                  });
            }
            return null;
          },
        );
      },
    );
  }