Implement Flutter’s BLoC architecture
2 min readJan 8, 2019
Implement Flutter’s BLoC architecture
I will show you how to implement the famous BLoC architecture by Flutter.
Constitution
The composition is like this.
I will do the package composition like this.
Implementation
Let’s paste the source code.
Prepare and implement UIScreen.
- main.dart
import 'package:flutter/material.dart';
import 'package:flutter_app_bloc_sample_app/src/app.dart';
void main() => runApp(App());
- app.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_bloc_sample_app/src/ui/scenery_list.dart';
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark(),
home: Scaffold(
body: SceneryList(),
),
);
}
}
UI Screen
- ui/scenery_list.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app_bloc_sample_app/src/blocs/scenery_bloc.dart';
import 'package:flutter_app_bloc_sample_app/src/models/image_model.dart';
class SceneryList extends StatelessWidget {
final _bloc = SceneryBloc();
@override
Widget build(BuildContext context) {
_bloc.fetchAllScenery();
return Scaffold(
appBar: AppBar(
title : Text ( "Landscape image list" ),
),
body: StreamBuilder(
stream: _bloc.allScenery,
builder: (_, snapshot) {
if (snapshot.hasData) {
return _buildList(snapshot);
} else if (snapshot.hasError) {
return Text ( "An error occurred" + snapshot.error.toString ());
}
return Center(
child: CircularProgressIndicator(),
);
}),
);
}
Widget _buildList(AsyncSnapshot<List<ImageModel>> snapshot) {
return GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount : 2 ),
itemBuilder: (_, index) {
ImageModel model = snapshot.data[index];
return Image.network(model.imageUrl);
},
itemCount: snapshot.data.length,
);
}
}
It is the part of BLOC.
- scenery_bloc.dart
import 'package:rxdart/rxdart.dart';
import 'package:flutter_app_bloc_sample_app/src/models/image_model.dart';
import 'package:flutter_app_bloc_sample_app/src/resources/repository.dart';
class SceneryBloc {
final _repository = Repository();
final _sceneryFetcher = PublishSubject<List<ImageModel>>();
Observable<List<ImageModel>> get allScenery => _sceneryFetcher.stream;
fetchAllScenery() async {
List<ImageModel> imageModelList = await _repository.fetchAllProvider();
_sceneryFetcher.sink.add(imageModelList);
}
has () {
_sceneryFetcher.close();
}
}
Next, Repository
import 'package:flutter_app_bloc_sample_app/src/models/image_model.dart';
import 'scenery_image_provider.dart';
class Repository {
final provider = new SceneryImageProvider();
Future<List<ImageModel>> fetchAllProvider() => provider.fetchImageList();
}
Next, Network Provider
import 'package:flutter_app_bloc_sample_app/src/models/image_model.dart';
import 'package:http/http.dart' show Client;
import 'dart:convert';
class SceneryImageProvider {
Client Client = Customer ();
Future < List < ImageModel >> fetchImageList () async {
/ / I prepared the Json. So please use it.
final response = await client. get (
"https://firebasestorage.googleapis.com/v0/b/blog-1a47d.appspot.com/o/json%2Fdata.json?alt=media&token=e67da5e7-b8d4-4000-9dc3 -394e6a5d1549 " );
print(response.body);
if (response.statusCode == 200) {
// success
List<dynamic> jsonArray = JsonDecoder().convert(response.body);
return jsonArray.map((i) => ImageModel(i)).toList();
} else {
// fail
throw Exception('Failed to load post');
}
}
}
This is completed.
The actual moving image will be below.
I put the source code in this repository.