Counter
The classic example. Simple state management with increment and decrement.
ViewModel
dart
import 'package:piper/piper.dart';
class CounterViewModel extends ViewModel {
late final count = state(0);
void increment() => count.update((c) => c + 1);
void decrement() => count.update((c) => c - 1);
void reset() => count.value = 0;
}Widget
dart
import 'package:flutter/material.dart';
import 'package:flutter_piper/flutter_piper.dart';
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final vm = context.vm<CounterViewModel>();
return Scaffold(
appBar: AppBar(
title: Text('Counter'),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: vm.reset,
),
],
),
body: Center(
child: vm.count.build(
(count) => Text(
'$count',
style: Theme.of(context).textTheme.displayLarge,
),
),
),
floatingActionButton: Column(
mainAxisSize: MainAxisSize.min,
children: [
FloatingActionButton(
heroTag: 'increment',
onPressed: vm.increment,
child: Icon(Icons.add),
),
SizedBox(height: 8),
FloatingActionButton(
heroTag: 'decrement',
onPressed: vm.decrement,
child: Icon(Icons.remove),
),
],
),
);
}
}Setup
dart
import 'package:flutter/material.dart';
import 'package:flutter_piper/flutter_piper.dart';
void main() {
runApp(
ViewModelScope(
create: [() => CounterViewModel()],
child: MaterialApp(home: CounterPage()),
),
);
}What's Happening
state(0)— Creates aStateHolder<int>with initial value0update()— Transforms the current value.build()— Rebuilds theTextwidget when count changes- Lifecycle — StateHolder is disposed when ViewModel disposes
