Last active
March 29, 2023 20:23
-
-
Save saad-palapa/f2eaa8c45e239aced25f2bddbee6da44 to your computer and use it in GitHub Desktop.
Custom flutter state management by wrapping 3rd party state management libraries
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/widgets.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
// this is an interface to a state management library | |
// clients of this library should not depend on any specific state management library | |
class Published<T> { | |
final _CubitWrapper<T> _cubit; | |
Published(T val) : _cubit = _CubitWrapper(val); | |
T get val => _cubit.state; | |
set val(T newVal) => _cubit.update(newVal); | |
Future<void> close() => _cubit.close(); | |
} | |
// this class is needed because Cubit.emit() is @protected | |
class _CubitWrapper<T> extends Cubit<T> { | |
_CubitWrapper(T state) : super(state); | |
void update(T newVal) => emit(newVal); | |
@override | |
Future<void> close() async { | |
print("Closing cubit, state=$state"); | |
return super.close(); | |
} | |
} | |
class PublishedConsumer<T> extends BlocConsumer<_CubitWrapper<T>, T> { | |
PublishedConsumer._({ | |
required Published<T> published, | |
required Widget Function(BuildContext, T) builder, | |
required void Function(BuildContext, T) listener, | |
}) : super(bloc: published._cubit, builder: builder, listener: listener); | |
factory PublishedConsumer.withContext({ | |
required Published<T> published, | |
Widget Function(BuildContext, T)? builder, | |
void Function(BuildContext, T)? listener, | |
}) { | |
return PublishedConsumer._( | |
published: published, | |
builder: builder ?? (_, __) => Container(), | |
listener: listener ?? (_, __) => null, | |
); | |
} | |
factory PublishedConsumer.new({ | |
required Published<T> published, | |
Widget Function(T)? builder, | |
void Function(T)? listener, | |
}) { | |
return PublishedConsumer._( | |
published: published, | |
builder: builder == null ? (_, __) => Container() : (_, v) => builder(v), | |
listener: listener == null ? (_, __) => null : (_, v) => listener(v), | |
); | |
} | |
} | |
// sample implementation | |
class LibraryScreen extends View<LibraryPage> { | |
LibraryScreen() : super(LibraryPage()); | |
LibraryPage get page => viewModel; | |
@override | |
Widget build(BuildContext context) { | |
return Column( | |
children: [ | |
ChipWheel(LibraryChips.values, onSelect: page.chipTapped), | |
Expanded( | |
child: PublishedConsumer( | |
published: page.chip, | |
builder: (_) => Text(page.chip.name), | |
), | |
), | |
], | |
); | |
} | |
} | |
class LibraryPage extends ViewModel { | |
final chip = Published(LibraryChips.all); | |
LibraryPage(); | |
void chipTapped(LibraryChips chip) => this.chip.val = chip; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment