Menu
CoddyTech

传递值的回调

本课属于 Coddy Flutter 学习旅程的“状态管理”单元。第 3 课,共 27 课。

回调可以把一个值传回上层。下面的尺寸选择器有三个按钮,页面需要知道你点了哪一个。

给回调添加一个参数。类型 void Function(String) 表示一个接收 String 并且不返回任何内容的函数:

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'),
    );
  }
}

每个按钮都会用一个小函数包住调用,() => onPick('S'),这样它会在点击时运行,而不是在构建时运行。父组件会将这个值作为参数接收并保存:

SizePicker(
  onPick: (picked) {
    setState(() {
      size = picked;
    });
  },
)

Flutter 为相同的类型提供了一个简短名称:ValueChanged<String>。许多内置组件都会使用它,例如 TextField 的 onChanged。

challenge icon

挑战

中等

让尺码按钮正常工作:

  • 给 SizePicker 添加字段 final void Function(String) onPick,并通过其构造函数设置。
  • 让每个按钮都用自己的字母调用 onPick。
  • 在页面上显示所选尺码:Size: S、Size: M 或 Size: L。

亲手试试

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')),
      ],
    );
  }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

状态管理中的所有课

自己练习: Flutter 在线编译器