Menu
CoddyTech

Передача callback-функции дочернему компоненту

Часть раздела Управление состоянием путешествия по Flutter на Coddy. Урок 2 из 27.

Значение передаётся от родителя к дочернему элементу. Нажатие работает наоборот: кнопка находится в дочернем элементе, а счёт, который она изменяет, принадлежит родителю.

Родитель передаёт дочернему элементу функцию, а дочерний элемент вызывает её. Функция без параметров, которая ничего не возвращает, имеет тип VoidCallback:

class AddButton extends StatelessWidget {
  const AddButton({super.key, required this.onAdd});

  final VoidCallback onAdd;

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(onPressed: onAdd, child: Text('Add point'));
  }
}

Родитель задаёт действие при нажатии, используя setState, как обычно:

AddButton(
  onAdd: () {
    setState(() {
      score++;
    });
  },
)

Напиши onPressed: onAdd, а не onAdd(). В первом случае функция передаётся кнопке для последующего вызова. Во втором она вызывается сразу во время построения, а кнопке передаётся результат её выполнения.

challenge icon

Задание

Легко

Кнопка Add point находится в виджете AddButton, и пока она ничего не делает.

  • Добавь в AddButton поле final VoidCallback onAdd, задаваемое конструктором.
  • Используй его в качестве onPressed кнопки.
  • На странице передай функцию, которая увеличивает score на 1 внутри setState.

Попробуйте сами

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> {
  int score = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Score: $score', style: const TextStyle(fontSize: 32)),
            const SizedBox(height: 16),
            const AddButton(),
          ],
        ),
      ),
    );
  }
}

class AddButton extends StatelessWidget {
  const AddButton({super.key});

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {},
      child: const Text('Add point'),
    );
  }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Управление состоянием

Потренируйтесь самостоятельно: Онлайн-компилятор Flutter