leulit_flutter_actionmanager 1.0.2
leulit_flutter_actionmanager: ^1.0.2 copied to clipboard
...
example/lib/main.dart
import 'package:flutter/material.dart' hide ActionDispatcher;
import 'package:leulit_flutter_actionmanager/leulit_flutter_actionmanager.dart';
void main() {
// Configurar logger (opcional)
ActionDispatcher.configureLogger(
enabled: true,
showTimestamp: true,
);
runApp(const MyApp());
}
/// Enum de acciones de ejemplo
enum AppAction {
increment,
decrement,
reset,
randomNumber,
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Action Dispatcher Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _counter = 0;
@override
void initState() {
super.initState();
// Registrar handlers
ActionDispatcher.onVoid(AppAction.increment, () {
setState(() => _counter++);
});
ActionDispatcher.onVoid(AppAction.decrement, () {
setState(() => _counter--);
});
ActionDispatcher.onVoid(AppAction.reset, () {
setState(() => _counter = 0);
});
ActionDispatcher.on<int>(AppAction.randomNumber, (number) {
if (number != null) {
setState(() => _counter = number);
}
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Action Dispatcher Demo'),
actions: [
IconButton(
icon: const Icon(Icons.info_outline),
onPressed: () {
// Mostrar estadísticas
ActionDispatcher.printSummary();
// También en UI
showDialog(
context: context,
builder: (context) => const StatsDialog(),
);
},
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Counter Value:', style: TextStyle(fontSize: 20)),
Text(
'$_counter',
style: Theme.of(context).textTheme.displayLarge,
),
const SizedBox(height: 40),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton.icon(
icon: const Icon(Icons.remove),
label: const Text('Decrement'),
onPressed: () {
ActionDispatcher.dispatch(AppAction.decrement);
},
),
const SizedBox(width: 10),
ElevatedButton.icon(
icon: const Icon(Icons.add),
label: const Text('Increment'),
onPressed: () {
ActionDispatcher.dispatch(AppAction.increment);
},
),
],
),
const SizedBox(height: 20),
ElevatedButton.icon(
icon: const Icon(Icons.refresh),
label: const Text('Reset'),
onPressed: () {
ActionDispatcher.dispatch(AppAction.reset);
},
),
const SizedBox(height: 20),
ElevatedButton.icon(
icon: const Icon(Icons.shuffle),
label: const Text('Random Number'),
onPressed: () {
final random = DateTime.now().millisecond;
ActionDispatcher.dispatch(AppAction.randomNumber, data: random);
},
),
const SizedBox(height: 40),
const SecondWidget(),
],
),
),
);
}
}
/// Widget adicional que también escucha las mismas acciones
class SecondWidget extends StatefulWidget {
const SecondWidget({super.key});
@override
State<SecondWidget> createState() => _SecondWidgetState();
}
class _SecondWidgetState extends State<SecondWidget> {
int _localCounter = 0;
@override
void initState() {
super.initState();
// Este widget también responde a las acciones
ActionDispatcher.onVoid(AppAction.increment, () {
setState(() => _localCounter++);
});
ActionDispatcher.onVoid(AppAction.reset, () {
setState(() => _localCounter = 0);
});
}
@override
Widget build(BuildContext context) {
return Card(
margin: const EdgeInsets.all(16),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
children: [
const Text(
'This widget also listens to actions!',
style: TextStyle(fontWeight: FontWeight.bold),
),
const SizedBox(height: 8),
Text('Local counter: $_localCounter'),
],
),
),
);
}
}
/// Dialog que muestra estadísticas
class StatsDialog extends StatelessWidget {
const StatsDialog({super.key});
@override
Widget build(BuildContext context) {
final stats = ActionDispatcher.getStats();
return AlertDialog(
title: const Text('📊 Dispatcher Stats'),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Total Actions: ${stats.totalActions}'),
Text('Total Handlers: ${stats.totalHandlers}'),
Text('Total Dispatches: ${stats.totalDispatches}'),
const SizedBox(height: 16),
const Text('Action Details:',
style: TextStyle(fontWeight: FontWeight.bold)),
...AppAction.values.map((action) {
final metadata = ActionDispatcher.getMetadata(action);
return Padding(
padding: const EdgeInsets.only(top: 8),
child: Text(
'${action.name}: ${metadata.handlerCount} handlers, '
'${metadata.dispatchCount} dispatches',
style: const TextStyle(fontSize: 12),
),
);
}),
],
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Close'),
),
],
);
}
}