maac_mvvm 0.2.3
maac_mvvm: ^0.2.3 copied to clipboard
maac_mvvm is a package supporting easy MVVM pattern implementation without any dependency injection wrapping, allowing freedom of choice.
maac_mvvm #
The core package of the MAAC ecosystem. It provides the base classes for the MVVM pattern and a lifecycle management system that mirrors the robustness of Android development.
🚀 Key Features #
- Lifecycle Synchronization: Android-inspired
onResume,onPause, andonDisposehooks. - Reactive State:
StreamDatafor clean data binding. - Efficient Rebuilds:
StreamDataConsumerfor granular UI updates, with an optionaluseCachepredicate to skip rebuilding for values that shouldn't visually change the UI. - Combining Multiple Streams:
StreamDataConsumer2/StreamDataConsumer3for rebuilding off 2 or 3StreamDatasources at once, orMergeStreamDataConsumerfor combining any number of them.
📖 Usage #
1. Define your ViewModel #
class CounterViewModel extends ViewModel {
late final _counter = 0.mutableData(this);
late final counter = _counter.streamData;
void increment() => _counter.postValue(counter.data + 1);
}
2. Build your UI #
class CounterPage extends ViewModelWidget<CounterViewModel> {
@override
CounterViewModel createViewModel() => CounterViewModel();
@override
Widget build(BuildContext context, CounterViewModel viewModel) {
return Scaffold(
body: Center(
child: StreamDataConsumer<int>(
streamData: viewModel.counter,
builder: (context, data) => Text('$data'),
),
),
floatingActionButton: FloatingActionButton(
onPressed: viewModel.increment,
child: Icon(Icons.add),
),
);
}
}
3. Combine Multiple Streams #
Rebuild off more than one StreamData at once with StreamDataConsumer2/StreamDataConsumer3 —
each source's latest value is passed straight into the builder, fully typed, no manual combining:
StreamDataConsumer2<int, bool>(
streamData1: viewModel.counter,
streamData2: viewModel.isFavorite,
builder: (context, count, isFavorite) => Text('$count ${isFavorite ? '★' : ''}'),
)
For more than 3 sources, or a source count that isn't known ahead of time, drop down to
MergeStreamDataConsumer — the primitive StreamDataConsumer2/3 are built on. It only
signals "something changed, rebuild"; read whichever StreamData.data you actually need
directly inside the builder:
MergeStreamDataConsumer(
streams: [viewModel.counter, viewModel.isFavorite, viewModel.themeLabel],
builder: (context) => Text(
'${viewModel.counter.data} ${viewModel.isFavorite.data ? '★' : ''} (${viewModel.themeLabel.data})',
),
)
All 3 rebuild whenever any source emits — there's no pairing/waiting between sources, so one fast-updating stream never gets held back by a slower one.
🧭 Documentation #
For detailed API specifications, installation guides, and tutorials, please visit our centralized documentation hub:
Specific Guides: #
🤝 Contributing #
Contributions are welcome! Please visit the main repository for more information.