Callbacks That Send a Value
Part of the State Management section of Coddy's Flutter journey. Lesson 3 of 27.
A callback can carry a value back up. The size picker below has three buttons, and the page needs to know which one was tapped.
Give the callback a parameter. The type void Function(String) is a function that takes a String and returns nothing:
class SizePicker extends StatelessWidget {
const SizePicker({super.key, required this.onPick});
final void Function(String) onPick;
@override
Widget build(BuildContext context) {
return OutlinedButton(
onPressed: () => onPick('S'),
child: Text('S'),
);
}
}Each button wraps the call in a small function, () => onPick('S'), so it runs on the tap and not during the build. The parent receives the value as a parameter and keeps it:
SizePicker(
onPick: (picked) {
setState(() {
size = picked;
});
},
)Flutter has a short name for the same type: ValueChanged<String>. Many built in widgets use it, such as the onChanged of a TextField.
Challenge
MediumMake the size buttons work:
- Give
SizePickera fieldfinal void Function(String) onPick, set by its constructor. - Make each button call
onPickwith its own letter. - In the page, show the picked size:
Size: S,Size: MorSize: L.
Try it yourself
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(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String size = 'M';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('T-shirt')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text('Size: $size', style: const TextStyle(fontSize: 32)),
const SizedBox(height: 16),
const SizePicker(),
],
),
),
);
}
}
class SizePicker extends StatelessWidget {
const SizePicker({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(onPressed: () {}, child: const Text('S')),
const SizedBox(width: 8),
OutlinedButton(onPressed: () {}, child: const Text('M')),
const SizedBox(width: 8),
OutlinedButton(onPressed: () {}, child: const Text('L')),
],
);
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in State Management
1Lifting State Up
Pass State to a ChildPass a Callback to a ChildCallbacks That Send a ValueLift State UpPractice on your own: Online Flutter compiler