web-dev-qa-db-ja.com

showModalBottomSheet内のProvided(Provider.of())値にアクセスする方法は?

flutter_bloc からのBlocProviderがあるウィジェットツリー内にFloatingActionButtonがあります。このようなもの:

_BlocProvider(
  builder: (context) {
    SomeBloc someBloc = SomeBloc();
    someBloc.dispatch(SomeEvent());

    return someBloc;
  },
  child: Scaffold(
    body: ...
    floatingActionButton: FloatingActionButton(
      onPressed: _openFilterSchedule,
      child: Icon(Icons.filter_list),
    ),
  )
);
_

これはモーダルのボトムシートを開きます:

_void _openFilterSchedule() {
    showModalBottomSheet<void>(
      context: context,
      builder: (BuildContext context) {
        return TheBottomSheet();
      },
    );
  }
_

SomeBloc内でBlocProvider.of<SomeBloc>(context)を使用してTheBottomSheetにアクセスしようとしていますが、次のエラーが発生します。

_BlocProvider.of() called with a context that does not contain a Bloc of type SomeBloc.
_

https://stackoverflow.com/a/56533611/2457045 で説明されているソリューションを使用しようとしましたが、BottomSheetでのみ機能し、ModalBottomSheetでは機能しません。


注:これはBlocProviderまたは_flutter_bloc_に限定されません。 provider パッケージのプロバイダーはすべて同じ動作をします。

showModalBottomSheet内のBlocProvider.of<SomeBloc>(context)にアクセスするにはどうすればよいですか?

それを行うことができない場合、どのように適応するか https://stackoverflow.com/a/56533611/2457045 ソリューションをモーダルボトムシートに適用するには?

7
Henrique Arthur

Scaffoldウィジェットとその子を別のStatefulWidgetに分割する必要があります

単一のウィジェットから

class MainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      builder: (context) {
        SomeBloc someBloc = SomeBloc();
        someBloc.dispatch(SomeEvent());
        return someBloc;
      },
      child: Scaffold(
        body: ...
        floatingActionButton: FloatingActionButton(
          onPressed: _openFilterSchedule,
          child: Icon(Icons.filter_list),
        ),
      )
    );
  }
}

これら2つのウィジェットに分割

class MainScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      builder: (context) {
        SomeBloc someBloc = SomeBloc();
        someBloc.dispatch(SomeEvent());
        return someBloc;
      },
      child: Screen(),
    );
  }
}

と..

class Screen extends StatelessWidget {

  void _openFilterSchedule() {
    showModalBottomSheet<void>(
      context: context,
      builder: (BuildContext context) {
        return TheBottomSheet();
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ...
      floatingActionButton: FloatingActionButton(
        onPressed: _openFilterSchedule,
        child: Icon(Icons.filter_list),
      ),
    );
  }
}
0
ejabu