Created
December 8, 2021 17:09
-
-
Save Lootwig/c31f3a2a6e1f8b8c54be802fb47ae669 to your computer and use it in GitHub Desktop.
bloc_maybe_statechange
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
void main() { | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
home: Builder(builder: (context) { | |
return BlocProvider( | |
create: (context) { | |
return DataBloc(() { | |
ScaffoldMessenger.of(context).showSnackBar( | |
const SnackBar(content: Text('Bloc has no new data :(')), | |
); | |
}); | |
}, | |
child: const FirstScreen(), | |
); | |
}), | |
); | |
} | |
} | |
class FirstScreen extends StatefulWidget { | |
const FirstScreen({ | |
Key? key, | |
}) : super(key: key); | |
@override | |
State<FirstScreen> createState() => _FirstScreenState(); | |
} | |
class _FirstScreenState extends State<FirstScreen> { | |
bool _loading = false; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Center( | |
child: ElevatedButton( | |
onPressed: _loading | |
? null | |
: () async { | |
setState(() => _loading = true); | |
final bloc = context.read<DataBloc>(); | |
final stateUpdate = bloc.stream.first; | |
bloc.add( | |
const DataEvent()); // this will only cause a state change every second time | |
final newState = await stateUpdate; | |
setState(() => _loading = false); | |
Navigator.of(context).push( | |
MaterialPageRoute( | |
builder: (_) => SecondScreen(data: newState.data), | |
), | |
); | |
}, | |
child: const Text('Go to second screen'), | |
), | |
), | |
); | |
} | |
} | |
class SecondScreen extends StatelessWidget { | |
final List<int> data; | |
const SecondScreen({Key? key, required this.data}) : super(key: key); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(), | |
body: Center( | |
child: Text('New data is: $data. Now go back and try again.'), | |
), | |
); | |
} | |
} | |
class DataBloc extends Bloc<DataEvent, DataState> { | |
VoidCallback onNoNewData; | |
bool _hasNewData = true; | |
int newData = 1; | |
DataBloc(this.onNoNewData) : super(const DataInitial()) { | |
on<DataEvent>((event, emit) async { | |
if (_hasNewData) { | |
await Future.delayed( | |
const Duration(seconds: 2), | |
() => emit(DataState([newData++])), | |
); | |
} else { | |
onNoNewData(); | |
} | |
_hasNewData = !_hasNewData; | |
}); | |
} | |
} | |
class DataEvent { | |
const DataEvent(); | |
} | |
class DataState /*extends Equatable*/ { | |
final List<int> data; | |
const DataState(this.data); | |
@override | |
bool operator ==(Object other) { | |
return other is DataState && other.data.every(data.contains); | |
} | |
} | |
class DataInitial extends DataState { | |
const DataInitial() : super(const []); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment