flutter_blocのExampleの説明
flutter_blocのExampleは1つのBLoCと1つのCubitが使われています。これらを説明してみます。
Cubitの説明
Exampleで使われているのはThemeCubit
です。
動きの概要
Cubitを使ったコードは以下の3段階の動きをすることで見た目の更新をします。
- ユーザーがボタンを押す等の作業により、UIがCubitのメソッドを呼び出す。
- 呼び出されたCubitのメソッドがStateを変更して、その変更を通知する。
- 新しいStateを通知として受け取ったUIが再描画する。
ThemeCubitがやること
ThemeCubit
のコードがやっていることは次の2つになります。
- Stateの初期値は
_lightTheme
です。 -
toggleTheme()
が呼ばれるとその前後でThemeData
を反転させて変更を通知させます。
実際のコード
ThemeCubit
は以下のようなClassで、上の2つが行われています。
class ThemeCubit extends Cubit<ThemeData> {
/// ここで初期値を設定しています。
ThemeCubit() : super(_lightTheme);
static final _lightTheme = ThemeData(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
foregroundColor: Colors.white,
),
brightness: Brightness.light,
);
static final _darkTheme = ThemeData(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
foregroundColor: Colors.black,
),
brightness: Brightness.dark,
);
void toggleTheme() {
/// ここでThemeDataを反転させて変更通知をしています。
emit(state.brightness == Brightness.dark ? _lightTheme : _darkTheme);
}
}
CubitのtoggleTheme()
はCounterPage
のボタンを押すことで呼び出されます。
// class CounterPageから抜粋
Padding(
padding: const EdgeInsets.symmetric(vertical: 5.0),
child: FloatingActionButton(
child: const Icon(Icons.brightness_6),
/// ここでCubitのtoggleThemeを呼び出しています。
onPressed: () => context.read<ThemeCubit>().toggleTheme(),
),
),
CubitのtoggleTheme()
の中で、emit()
というメソッドによって新しいStateが通知されます。これを App
Class内のBlocBuilder
が受け取って再描画しています。
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => ThemeCubit(),
/// 新しいStateを受け取って再描画する。
child: BlocBuilder<ThemeCubit, ThemeData>(builder: (_, theme) {
return MaterialApp(theme: theme, home: BlocProvider(create: (_) => CounterBloc(), child: CounterPage()));
}));
}
}
emit()の動き
Cubitが独自で使っているメソッドがemit()
です。これはBLoCでは使いません。このメソッドはStateが変わった際にStreamによりbroadcastします。Stateが変わらなければ通知しないので、無駄な再描画はされないようになっています。
興味のある方はコードを読んでみてください。