This article walks you through a complete example of passing functions from a parent widget to a child widget in Flutter (the child widget can be stateless or stateful, and the passed functions can be called with parameters).
The Child Is A Stateless Widget
Example Preview
We’ll build a small app that contains 2 widgets named HomePage (the parent) and ChildWidget (the child). The child widget has 2 buttons that will call a function passed from the parent (this function can display a dialog and print something to the terminal) when one of them gets pressed.
Here’s how it works:
The Code
1. HomeWidget is implemented in home_page.dart and ChildWidget is implemented in a separate file named child_widget.dart. File structure:
.
├── child_widget.dart
├── home_page.dart
└── main.dart
2. The code in child_widget.dart:
import 'package:flutter/material.dart';
class ChildWidget extends StatelessWidget {
final Function buttonHandler;
const ChildWidget({Key? key, required this.buttonHandler}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () => buttonHandler('Hello'),
child: const Text('Say Hello')),
ElevatedButton(
onPressed: () => buttonHandler('Goodbye'),
child: const Text('Say Goodbye')),
],
);
}
}
3. The code in home_page.dart:
// home_page.dart
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import './child_widget.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// This function will be passed to the child widget
void _passedFunction(String input) {
// Print the input to the console
if (kDebugMode) {
print(input);
}
// Show a dialog with the input
showDialog(
context: context,
builder: (_) => Dialog(
child: Container(
width: 300,
height: 200,
color: Colors.amberAccent,
child: Center(
child: Text(
input,
style: const TextStyle(fontSize: 24),
))),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('KindaCode.com')),
body: Center(
child: ChildWidget(
buttonHandler: _passedFunction,
),
),
);
}
}
4. Wire up everything in main.dart:
// home_page.dart
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import './child_widget.dart';
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
// This function will be passed to the child widget
void _passedFunction(String input) {
// Print the input to the console
if (kDebugMode) {
print(input);
}
// Show a dialog with the input
showDialog(
context: context,
builder: (_) => Dialog(
child: Container(
width: 300,
height: 200,
color: Colors.amberAccent,
child: Center(
child: Text(
input,
style: const TextStyle(fontSize: 24),
))),
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('KindaCode.com')),
body: Center(
child: ChildWidget(
buttonHandler: _passedFunction,
),
),
);
}
}
The Child Is A Stateful Widget
We will continue to work with the example in the previous section. Everything remains the same, except ChildWidget is now stateful. The code in child_widget.dart:
// child_widget.dart
import 'package:flutter/material.dart';
class ChildWidget extends StatefulWidget {
final Function buttonHandler;
const ChildWidget({Key? key, required this.buttonHandler}) : super(key: key);
@override
State<ChildWidget> createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () => widget.buttonHandler('Hello'),
child: const Text('Say Hello')),
ElevatedButton(
onPressed: () => widget.buttonHandler('Goodbye'),
child: const Text('Say Goodbye')),
],
);
}
}
Conclusion
We’ve walked through an end-to-end example that demonstrates how to pass a function (with or without parameters) from a parent widget to a child widget. If you’d like to explore more exciting and new things about Flutter, take a look at the following articles:
- Flutter: Import only 1 class from a file containing multi classes
- Flutter: Using same-name classes imported from different files
- 2 Ways to Create Typewriter Effects in Flutter
- Flutter: Convert UTC Time to Local Time and Vice Versa
- Flutter: Changing App Display Name for Android & iOS
- Flutter: SliverGrid example
You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.