Kinda Code
Home/Flutter/How to pass functions to child widgets in Flutter

How to pass functions to child widgets in Flutter

Last updated: February 15, 2023

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:

You can also take a tour around our Flutter topic page and Dart topic page to see the latest tutorials and examples.