0 purchases
ecco
Ecco #
Ecco is a simple, MVVM-focused state management solution for Flutter. It provides an intuitive way to manage application state and rebuild UI components efficiently.
Features #
Lightweight and easy to understand
MVVM architecture support
Efficient UI updates with fine-grained rebuilds
Customizable logging functionality
Built-in support for Equatable for efficient state comparisons
Installation #
Add ecco to your pubspec.yaml file:
dependencies:
ecco: ^0.0.1+6
copied to clipboard
Then run:
flutter pub get
copied to clipboard
Basic Usage #
Here's a simple counter app example demonstrating the basic usage of Ecco:
import 'package:flutter/material.dart';
import 'package:ecco/ecco.dart';
void main() {
Eccoes.enable();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Ecco MVVM Counter',
theme: ThemeData(primarySwatch: Colors.blue),
home: EccoProvider<CounterModel>(
notifier: CounterViewModel(),
child: const CounterView(),
),
);
}
}
class CounterView extends StatelessWidget {
const CounterView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Ecco MVVM Counter')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
EccoBuilder<CounterModel>(
builder: (context, model) {
return Text(
'Count: ${model.count}',
style: Theme.of(context).textTheme.headlineMedium,
);
},
),
const SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: context.ecco<CounterViewModel>().decrement,
child: const Text('Decrement'),
),
const SizedBox(width: 20),
EccoConsumer<CounterModel, CounterViewModel>(
builder: (context, model, viewModel) {
return ElevatedButton(
onPressed: viewModel.increment,
child: const Text('Increment'),
);
},
),
],
),
],
),
),
);
}
}
class CounterModel {
final int count;
CounterModel({this.count = 0});
}
class CounterViewModel extends EccoNotifier<CounterModel> {
CounterViewModel() : super(CounterModel());
void increment() {
ripple(CounterModel(count: state.count + 1));
}
void decrement() {
ripple(CounterModel(count: state.count - 1));
}
}
copied to clipboard
Core Concepts #
The ripple Method #
The ripple method is a core concept in Ecco for updating state. It's used within EccoNotifier subclasses to propagate state changes.
Key points about ripple:
Purpose: ripple is used to update the state and notify listeners of the change.
Efficient Updates: It only notifies listeners if the new state is different from the current state.
Immutability: ripple encourages the use of immutable state objects. Instead of modifying the existing state, you create a new state object.
Usage: Call ripple with a new state object whenever you want to update the state.
Automatic Rebuilds: When ripple is called, it automatically triggers a rebuild of all widgets listening to this notifier.
Equatable Support: If your state class extends Equatable, ripple will use its equality implementation to determine if the state has changed.
By using ripple, you ensure that state updates are handled efficiently and consistently throughout your application.
void updateUserName(String newName) {
ripple(UserState(name: newName, age: state.age));
}
copied to clipboard
EccoNotifier #
EccoNotifier is the base class for managing state. It extends ChangeNotifier and provides methods to update state and notify listeners.
class CounterViewModel extends EccoNotifier<CounterModel> {
CounterViewModel() : super(CounterModel());
void increment() {
ripple(CounterModel(count: state.count + 1));
}
}
copied to clipboard
EccoProvider #
EccoProvider makes an EccoNotifier available to its descendants in the widget tree.
EccoProvider<CounterModel>(
notifier: CounterViewModel(),
child: const CounterView(),
)
copied to clipboard
EccoBuilder #
EccoBuilder rebuilds its child widget when the state of an EccoNotifier changes.
EccoBuilder<CounterModel>(
builder: (context, model) {
return Text('Count: ${model.count}');
},
)
copied to clipboard
EccoConsumer #
EccoConsumer provides access to both the state and the notifier in its builder function.
EccoConsumer<CounterModel, CounterViewModel>(
builder: (context, model, viewModel) {
return ElevatedButton(
onPressed: viewModel.increment,
child: Text('Increment'),
);
},
)
copied to clipboard
Extension Method: ecco
Ecco provides a convenient extension method on BuildContext to easily access notifiers:
ElevatedButton(
onPressed: context.ecco<CounterViewModel>().increment,
child: const Text('Increment'),
),
copied to clipboard
This extension method retrieves the EccoNotifier of type T from the widget tree, allowing for a more concise syntax when accessing notifiers.
Logging #
Ecco provides customizable logging functionality. Enable logging and set the desired log level in your app's main function:
void main() {
Eccoes.enable();
runApp(const MyApp());
}
copied to clipboard
Best Practices #
Keep your models immutable and use the Equatable mixin for efficient comparisons.
Use EccoBuilder for widgets that only need to read the state.
Use EccoConsumer when you need access to both the state and the notifier.
Leverage the ecco<T>() extension method for concise notifier access.
Always use the ripple method to update state in your ViewModels.
License #
This project is licensed under the MIT License - see the LICENSE file for details.
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.