import 'dart:async';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: CounterScreen(),
);
}
}
class CounterBloc {
int _counter = 0;
final _counterController = StreamController<int>.broadcast();
Stream<int> get counterStream => _counterController.stream;
void increment() {
_counter++;
_counterController.sink.add(_counter);
}
void decrement() {
_counter--;
_counterController.sink.add(_counter);
}
void dispose() {
_counterController.close();
}
}
class CounterScreen extends StatefulWidget {
const CounterScreen({super.key});
@override
State<CounterScreen> createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
final CounterBloc _bloc = CounterBloc();
@override
void dispose() {
_bloc.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Counter App')),
body: Center(
child: StreamBuilder<int>(
stream: _bloc.counterStream,
initialData: 0,
builder: (context, snapshot) {
return Text(
'${snapshot.data}',
style: const TextStyle(fontSize: 48),
);
},
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
onPressed: _bloc.decrement,
tooltip: 'Decrement',
child: const Icon(Icons.remove),
),
const SizedBox(width: 16),
FloatingActionButton(
onPressed: _bloc.increment,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
],
),
);
}
}This app uses the BLoC pattern to separate business logic from UI.
The CounterBloc class manages the counter state internally and exposes a Stream<int> to notify listeners about changes.
The UI listens to this stream using StreamBuilder and rebuilds the counter text whenever the value changes.
Increment and decrement buttons call methods on the BLoC to update the counter, which then emits the new value through the stream.
This keeps the UI simple and reactive, while the BLoC handles all state management.