Skip to content

Instantly share code, notes, and snippets.

@benoitjadinon
Last active March 3, 2019 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benoitjadinon/b35c2e60aa5f2ecced2801693aab4e29 to your computer and use it in GitHub Desktop.
Save benoitjadinon/b35c2e60aa5f2ecced2801693aab4e29 to your computer and use it in GitHub Desktop.
import 'package:flutter/widgets.dart';
// (c) Didier Boelens
// https://www.didierboelens.com/2018/12/reactive-programming---streams---bloc---practical-use-cases/
Type _typeOf<T>() => T;
abstract class BlocBase {
void dispose();
}
class BlocProvider<T extends BlocBase> extends StatefulWidget {
BlocProvider({
Key key,
@required this.child,
@required this.bloc,
}): super(key: key);
final Widget child;
final T bloc;
@override
_BlocProviderState<T> createState() => _BlocProviderState<T>();
static T of<T extends BlocBase>(BuildContext context){
final type = _typeOf<_BlocProviderInherited<T>>();
_BlocProviderInherited<T> provider =
context.ancestorInheritedElementForWidgetOfExactType(type)?.widget;
return provider?.bloc;
}
}
class _BlocProviderState<T extends BlocBase> extends State<BlocProvider<T>>{
@override
void dispose(){
widget.bloc?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context){
return new _BlocProviderInherited<T>(
bloc: widget.bloc,
child: widget.child,
);
}
}
class _BlocProviderInherited<T> extends InheritedWidget {
_BlocProviderInherited({
Key key,
@required Widget child,
@required this.bloc,
}) : super(key: key, child: child);
final T bloc;
@override
bool updateShouldNotify(_BlocProviderInherited oldWidget) => false;
}
import 'package:flutter/widgets.dart';
import 'package:rxdart/rxdart.dart';
import 'package:winamp/helpers/BlocProvider.dart';
class StreamBuilderBloc<TB extends BlocBase, T> extends StatelessWidget
{
final StreamInBloc<T, TB> stream;
final AsyncWidgetBuilderWithBloc<T, TB> builder;
final T initialData;
TB _bloc;
StreamBuilderBloc({
Key key,
BuildContext context,
this.stream,
this.initialData,
@required this.builder
}) : assert(builder != null),
super(key:key)
{
_bloc = BlocProvider.of<TB>(context);
}
@override
Widget build(BuildContext context) {
return StreamBuilder<T>(
stream: stream(_bloc),
builder: (c,s) => builder(c, s, _bloc),
initialData:
(stream(_bloc) is BehaviorSubject<T>)
? (stream(_bloc) as BehaviorSubject<T>).value
: initialData,
);
}
}
typedef AsyncWidgetBuilderWithBloc<T, TB> = Widget Function(BuildContext context, AsyncSnapshot<T> snapshot, TB bloc);
typedef StreamInBloc<T, TB> = Stream<T> Function(TB bloc);
StreamBuilderBloc<PlayerBloc, Song>(
context: context,
stream: (b) => b.currentSongStream, // can only be a Stream of Song of the b PlayerBloc class
builder: (c, s, b) {
var song = s?.data ?? Song.empty();
return ...
}
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment