flutter_bloc
による状態管理 + プログレスダイアログ表示、Toast表示のようなサンプルが見つからなかったので書いておきます。
実現したいこと
flutter_bloc
で状態管理をしている画面で↓のようなシンプルな入力フォームをつくりたかった。
使用したライブラリ
flutter_bloc
bloc
fluttertoast
ソースコード
ダイアログ表示やToast表示は上位にBlocListnerを作れば簡単に出来そうでした。
fetch
や insert
はダミーです。
○SamplePage
sample_page.dart
class SamplePage extends StatelessWidget {
const SamplePage({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
body: BlocProvider(
create: (context) => SampleBloc(repository: SampleFirestoreRepositry()),
child: const _SampleBody(),
),
);
}
}
class _SampleBody extends StatelessWidget {
const _SampleBody({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocListener<SampleBloc, SampleState>(
bloc: BlocProvider.of<SampleBloc>(context)..add(InitEvent()),
listener: (context, state) {
// ダイアログ表示
if (state is SaveProgressState) {
_showLoadingDialog(context);
}
// ダイアログ閉じてToast表示
if (state is SaveSuccessState) {
Navigator.pop(context);
Fluttertoast.showToast(msg: "保存が完了しました");
}
},
child: BlocBuilder(
bloc: BlocProvider.of<SampleBloc>(context),
condition: (prev, state) {
return state is! SaveProgressState && state is! SaveSuccessState;
},
builder: (context, state) {
if (state is DispSuccessState) {
return _buildSuccess(context);
}
return Center(
child: CircularProgressIndicator(),
);
},
),
);
}
Widget _buildSuccess(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text("何かしらの入力フォーム"),
TextFormField(onSaved: (_text) => {}),
RaisedButton(
onPressed: () =>
BlocProvider.of<SampleBloc>(context).add(SaveEvent()),
child: Text("保存"),
)
],
);
}
void _showLoadingDialog(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return new Dialog(
child: Container(
margin: EdgeInsets.all(20.0),
child: new Column(
mainAxisSize: MainAxisSize.min,
children: [
new CircularProgressIndicator(),
new Container(
margin: new EdgeInsets.all(10.0), child: new Text("保存中")),
],
),
),
);
},
);
}
}
○SampleBloc
sample_bloc.dart
class SampleBloc extends Bloc<SampleEvent, SampleState> {
final SampleRepository _repository;
SampleBloc({SampleRepository repository})
: assert(repository != null),
_repository = repository,
super();
@override
SampleState get initialState => InitState();
@override
Stream<SampleState> mapEventToState(SampleEvent event) async* {
if (event is InitEvent) {
yield* _init(event);
} else if (event is SaveEvent) {
yield* _save(event);
}
}
Stream<SampleState> _init(InitEvent event) async* {
yield DispProgressState();
try {
// 2秒待つだけ
await _repository.fetch();
yield DispSuccessState();
} catch (_) {
yield DispFailureState(_);
}
}
Stream<SampleState> _save(SaveEvent event) async* {
yield SaveProgressState();
try {
// 2秒待つだけ
await _repository.insert();
yield SaveSuccessState();
} catch (_) {
yield SaveFailureState(_);
}
}
}
他力本願寺
Flutter勉強中です。
勉強中の気づきや指摘等頂いた際には、内容を更新していきます。
(訳:キレイな書き方教えてください)