LoginSignup
2

More than 3 years have passed since last update.

FlutterBlocでダイアログ表示やtoast表示

Last updated at Posted at 2020-02-07

flutter_bloc による状態管理 + プログレスダイアログ表示、Toast表示のようなサンプルが見つからなかったので書いておきます。

実現したいこと

flutter_bloc で状態管理をしている画面で↓のようなシンプルな入力フォームをつくりたかった。
sample.gif

使用したライブラリ

flutter_bloc
bloc
fluttertoast

ソースコード

ダイアログ表示やToast表示は上位にBlocListnerを作れば簡単に出来そうでした。
fetchinsert はダミーです。

○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(_);
    }
  }
}

他力本願寺:shinto_shrine:

Flutter勉強中です。
勉強中の気づきや指摘等頂いた際には、内容を更新していきます。
(訳:キレイな書き方教えてください:bow:

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
2