Skip to content

Instantly share code, notes, and snippets.

@felangel
Last active September 21, 2021 11:35
Show Gist options
  • Save felangel/68088378617e6d4b5fee06f070cafef4 to your computer and use it in GitHub Desktop.
Save felangel/68088378617e6d4b5fee06f070cafef4 to your computer and use it in GitHub Desktop.
Flutter Bloc Dio Download Example
import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter_download/download_service.dart';
import 'package:meta/meta.dart';
part 'download_event.dart';
part 'download_state.dart';
class DownloadBloc extends Bloc<DownloadEvent, DownloadState> {
final DownloadService downloadService;
DownloadBloc({@required this.downloadService})
: assert(downloadService != null);
@override
DownloadState get initialState => DownloadInitial();
@override
Stream<DownloadState> mapEventToState(DownloadEvent event) async* {
if (event is DownloadStarted) {
yield DownloadLoadInProgress();
downloadService.downloadFile(
progressCallback: (count, total) {
add(DownloadStatusChanged((count * 100 ~/ total)));
},
).catchError((_) => add(DownloadErrored()));
} else if (event is DownloadStatusChanged) {
yield event.progress == 100
? DownloadSuccess()
: DownloadLoadInProgress(progress: event.progress);
} else if (event is DownloadErrored) {
yield DownloadFailure();
}
}
}
part of 'download_bloc.dart';
@immutable
abstract class DownloadEvent extends Equatable {
@override
List<Object> get props => [];
}
class DownloadStarted extends DownloadEvent {}
class DownloadStatusChanged extends DownloadEvent {
final int progress;
DownloadStatusChanged(this.progress);
@override
List<Object> get props => [progress];
}
class DownloadErrored extends DownloadEvent {}
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
class DownloadService {
final Dio _dio;
DownloadService({Dio dio}) : _dio = dio ?? Dio();
Future<void> downloadFile({ProgressCallback progressCallback}) async {
final url =
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4';
final downloadDir = await getApplicationDocumentsDirectory();
final saveFilePath = '${downloadDir.path}/temp.mp4';
await _dio.download(url, saveFilePath, onReceiveProgress: progressCallback);
}
}
part of 'download_bloc.dart';
abstract class DownloadState extends Equatable {
@override
List<Object> get props => [];
}
class DownloadInitial extends DownloadState {}
class DownloadLoadInProgress extends DownloadState {
final int progress;
DownloadLoadInProgress({this.progress = 0});
@override
List<Object> get props => [progress];
}
class DownloadSuccess extends DownloadState {}
class DownloadFailure extends DownloadState {}
import 'package:flutter/material.dart';
import 'package:flutter_download/bloc/download_bloc.dart';
import 'package:flutter_download/download_service.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: MyHomePage());
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final DownloadBloc _downloadBloc = DownloadBloc(
downloadService: DownloadService(),
);
@override
void dispose() {
_downloadBloc.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Bloc Download Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
BlocBuilder(
bloc: _downloadBloc,
builder: (_, state) {
if (state is DownloadInitial) {
return Text('Please touch on Download FAB');
}
if (state is DownloadLoadInProgress) {
return Text('Downloading ${state.progress}%');
}
if (state is DownloadSuccess) {
return Text('Success!');
}
return Text('Failure');
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _downloadBloc.add(DownloadStarted()),
tooltip: 'Download',
child: const Icon(Icons.file_download),
),
);
}
}
name: flutter_download
description: A new Flutter application to demonstrate how to yield from callback using flutter_bloc
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
dio: ^3.0.9
bloc: ^4.0.0
flutter_bloc: ^4.0.0
meta: ^1.1.8
equatable: ^1.1.1
path_provider: ^1.6.11
flutter:
uses-material-design: true
@KanybekMomukeyev
Copy link

Thank, this is very helpfull, it was very hard to find in google.
It should be in documentaion.

@XbIK
Copy link

XbIK commented Sep 21, 2021

very usefull example, which helps to clear out how Bloc makes your app architecture more well structured

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment