Created
May 2, 2019 02:38
-
-
Save felangel/d9322837c07721b97ae2f7be541cabb2 to your computer and use it in GitHub Desktop.
flutter_bloc with flutter_hooks
This file contains hidden or 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:bloc/bloc.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
import 'package:flutter_hooks/flutter_hooks.dart'; | |
enum CounterEvent { increment, decrement } | |
class CounterBloc extends Bloc<CounterEvent, int> { | |
@override | |
int get initialState => 0; | |
@override | |
Stream<int> mapEventToState( | |
CounterEvent event, | |
) async* { | |
switch (event) { | |
case CounterEvent.increment: | |
yield currentState + 1; | |
break; | |
case CounterEvent.decrement: | |
yield currentState - 1; | |
break; | |
} | |
} | |
} | |
main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
routes: { | |
'/': (context) => MyPage(), | |
'/details': (context) => MyDetailsPage(), | |
}, | |
initialRoute: '/', | |
); | |
} | |
} | |
class MyPage extends HookWidget { | |
@override | |
Widget build(BuildContext context) { | |
final _counterBloc = useBloc(() => CounterBloc()); | |
return Scaffold( | |
appBar: AppBar( | |
title: Text('Bloc Hook'), | |
actions: <Widget>[ | |
IconButton( | |
icon: Icon(Icons.navigate_next), | |
onPressed: () { | |
Navigator.of(context).pushReplacementNamed('/details'); | |
}, | |
) | |
], | |
), | |
body: BlocBuilder<CounterEvent, int>( | |
bloc: _counterBloc, | |
builder: (BuildContext context, int count) { | |
return Center( | |
child: Text( | |
'$count', | |
style: TextStyle(fontSize: 24.0), | |
), | |
); | |
}, | |
), | |
floatingActionButton: Column( | |
crossAxisAlignment: CrossAxisAlignment.end, | |
mainAxisAlignment: MainAxisAlignment.end, | |
children: <Widget>[ | |
Padding( | |
padding: EdgeInsets.symmetric(vertical: 5.0), | |
child: FloatingActionButton( | |
child: Icon(Icons.add), | |
onPressed: () { | |
_counterBloc.dispatch(CounterEvent.increment); | |
}, | |
), | |
), | |
Padding( | |
padding: EdgeInsets.symmetric(vertical: 5.0), | |
child: FloatingActionButton( | |
child: Icon(Icons.remove), | |
onPressed: () { | |
_counterBloc.dispatch(CounterEvent.decrement); | |
}, | |
), | |
), | |
], | |
), | |
); | |
} | |
} | |
class MyDetailsPage extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(title: Text('Details')), | |
body: Center( | |
child: RaisedButton( | |
child: Text('Go Back'), | |
onPressed: () { | |
Navigator.of(context).pushReplacementNamed('/'); | |
}, | |
), | |
), | |
); | |
} | |
} | |
T useBloc<T extends Bloc>(T Function() blocFactory, | |
[List<Object> keys = const <dynamic>[]]) { | |
return Hook.use(_BlocHook( | |
blocFactory, | |
keys: keys, | |
)); | |
} | |
class _BlocHook<T extends Bloc> extends Hook<T> { | |
final T Function() blocFactory; | |
const _BlocHook( | |
this.blocFactory, { | |
List<Object> keys = const <dynamic>[], | |
}) : assert(blocFactory != null), | |
assert(keys != null), | |
super(keys: keys); | |
@override | |
_BlocHookState<T> createState() => _BlocHookState<T>(); | |
} | |
class _BlocHookState<T extends Bloc> extends HookState<T, _BlocHook<T>> { | |
T bloc; | |
@override | |
void initHook() { | |
super.initHook(); | |
bloc = hook.blocFactory(); | |
} | |
@override | |
T build(BuildContext context) { | |
return bloc; | |
} | |
@override | |
void dispose() { | |
bloc.dispose(); | |
super.dispose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment