1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

わたしのFlutterお勉強用Advent Calendar 2020

Day 5

flutter_blocを使ってみる その5 - 複数Stateを連続で返す処理

Posted at

以前書いた記事でBLoCは複数のStateを順次通知するような挙動ができると書きました
これを説明する良いチュートリアルがあったので紹介します。

チュートリアルは[こちら]です。(https://resocoder.com/2020/08/04/flutter-bloc-cubit-tutorial/)

サンプルアプリケーションの動き

このアプリケーションの動きは以下のようになります。

  • TextFieldに都市名を入力する
  • BlocまたはCubitが都市名入力を受け取り以下の順にStateを返す
    • Repository(ダミー)が気温データを取得中(1秒間)はLoading
    • 気温データを取得後はLoaded

Loading → Loaded というようにStateが変化します。

実際のコード: Cubit

Cubitのコードは以下のようになっています。
getWeather()メソッド内でデータ取得前後でStateをemit()をしています。

class WeatherCubit extends Cubit<WeatherState> {
  final WeatherRepository _weatherRepository;

  WeatherCubit(this._weatherRepository) : super(WeatherInitial());

  Future<void> getWeather(String cityName) async {
    try {
      // ここでStateを連続して通知しています。
      emit(WeatherLoading());
      final weather = await _weatherRepository.fetchWeather(cityName);
      emit(WeatherLoaded(weather));
    } on NetworkException {
      emit(WeatherError("Couldn't fetch weather. Is the device online?"));
    }
  }
}

実際のコード: Bloc

これをBlocで書くと以下のようになります。
mapEventToState()内でデータ取得前後でStateをyieldしています。

class WeatherBloc extends Bloc<WeatherEvent, WeatherState> {
  final WeatherRepository _weatherRepository;

  WeatherBloc(this._weatherRepository) : super(WeatherInitial());

  @override
  Stream<WeatherState> mapEventToState(
    WeatherEvent event,
  ) async* {
    if (event is GetWeather) {
      try {
      // ここでStateを連続して通知しています。
        yield WeatherLoading();
        final weather = await _weatherRepository.fetchWeather(event.cityName);
        yield WeatherLoaded(weather);
      } on NetworkException {
        yield WeatherError("Couldn't fetch weather. Is the device online?");
      }
    }
  }
}

CubitではなくBlocを使う方が一般的だと思います。この方法はBlocパターンではよく使うので把握しておくとよいと思います。

View側のコード

BlocBuilder(listenerを併用する場合はBlocConsumer)にて表示するWidgetを切り替えています。
ローディング中はCircularProgressIndicator()を表示しています。

その他の補足ポイント

== と hashCodeをオーバーライドしている

このサンプルではStateとEventにEquatableを用いていません。
なのでこちらの記事で説明したように ==hashCode をオーバーライドしています。

以上です。わかりやすいサンプルなのでぜひ参考にしてみてください。

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?