LoginSignup
7
3

More than 3 years have passed since last update.

Flutter Blocライブラリ メモ

Last updated at Posted at 2019-12-28

Flutterでblocパターンを実装する際に便利な blocライブラリの自分用メモ
まだ実装はしてないので、間違っているところが多いと思います。

Blocライブラリ → https://bloclibrary.dev/#/
Blocパターンとは → https://qiita.com/kabochapo/items/8738223894fb74f952d3

flutter_bloc 3.0.0 → https://pub.dev/packages/flutter_bloc

BlocProvider

基本

複数のサブツリーに指定したblocを提供する。
widget内で使用する場合は、BlocProvider.of<T>(context)でblocを利用する。ただこのままblocの値をwidgetに使っても、値が変更された時にwidgetはリビルドされないので注意する。値の変更をwidgetに反映するには、BlocBuilderを使用する。

BlocProvider(
  create: (BuildContext context) => BlocA(),
  child: ChildA(),
);

上記はBlocAを新しく作成し、childAのツリー内に渡している。
新しいblocではなく、既存のBlocをwidgetツリーの新しいルートで利用するには以下のようにする。

BlocProvider.value(
  value: BlocProvider.of<BlocA>(context),
  child: ScreenA(),
);

MultiBlocProvider

上で述べた方法だと、Blocが複数あるときに複雑なネストが生じる。

BlocProvider<BlocA>(
  create: (BuildContext context) => BlocA(),
  child: BlocProvider<BlocB>(
    create: (BuildContext context) => BlocB(),
    child: BlocProvider<BlocC>(
      create: (BuildContext context) => BlocC(),
      child: ChildA(),
    )
  )
)

これでは読みにくいので、MultiProviderを使う。MultiProviderは上のような複数のBlocProviderを1つにまとめてくれる。

MultiBlocProvider(
  providers: [
    BlocProvider<BlocA>(
      create: (BuildContext context) => BlocA(),
    ),
    BlocProvider<BlocB>(
      create: (BuildContext context) => BlocB(),
    ),
    BlocProvider<BlocC>(
      create: (BuildContext context) => BlocC(),
    ),
  ],
  child: ChildA(),
)

ブロックアクセス

widgetツリー全体でブロックにアクセスする方法 →
https://bloclibrary.dev/#/recipesflutterblocaccess
ローカルアクセス、ルートアクセス、グローバルアクセスの3つのシナリオについて記載されている。
ここでは、ユーザー情報の共有に使えそうなグローバルアクセスについて見ていく。

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (BuildContext context) => Bloc(), //グローバルに使いたいBloc
      child: MaterialApp(
        title: 'demo',
        home: Page(), 
      ),
    );
  }
}

MaterialAppをラップすることで、Blocのインスタンスをグローバルにアクセス可能にする。
widget全体で使いそうなユーザー情報やログイン情報のblocはここで作成する。

BlocBuilder

blocの状態が変わったら、widgetをリビルドする。

BlocLister

Blocの状態が変わったら、Blocを呼び出す。widgetはリビルドされない。

body: Center(
        child: BlocListener<WeatherBloc, WeatherState>(
          listener: (context, state) {
            if (state is WeatherLoaded) {
              BlocProvider.of<ThemeBloc>(context).add(
                WeatherChanged(condition: state.weather.condition),
              );
              _refreshCompleter?.complete();
              _refreshCompleter = Completer();
            }
          }
       )

「Flutter Weather Tutorial」: https://bloclibrary.dev/#/flutterweathertutorial
上のコードは「Flutter Weather Tutorial」からの引用である。
BlocBuilderと異なり、変更されたstateの値を処理に利用するだけで、widgetのリビルドは行わない。

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3