Menu
CoddyTech

获取返回结果

本课属于 Coddy Flutter 学习旅程的“列表和屏幕”单元。第 22 课,共 33 课。

有些屏幕用于提问:选择颜色、选择日期。答案必须返回到提出问题的屏幕。Navigator.pop 可以携带答案:

Navigator.pop(context, 'Green');

在另一端,Navigator.push 会返回一个 Future:这个值会在之后,也就是推入的屏幕弹出时到达。await 会等待它,而等待的函数要标记为 async:

onPressed: () async {
  final String? color = await Navigator.push(
    context,
    MaterialPageRoute(builder: (context) => const ColorScreen()),
  );
  if (color != null) {
    setState(() {
      chosen = color;
    });
  }
},

结果的类型是 String?:如果有人通过返回箭头离开,就不会发送任何内容,color 的值为 null。此时,if 会保留之前的选择。后面的单元会完整讲解 Future 和 await。

challenge icon

挑战

中等

选择颜色后,颜色页面会关闭,但主页始终收不到选择结果。让选择结果返回:

  • 在颜色页面中,使用颜色调用 Navigator.pop(context, color)
  • 在主页中,对 push 使用 await,如果返回了颜色,就显示 Your color: Green(其中的颜色替换为所选颜色)
  • 点击返回箭头离开时,保留原来的文本

亲手试试

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: HomeScreen(),
    );
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  String chosen = 'none';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Paint')),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            Text('Your color: $chosen', style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const ColorScreen()),
                );
              },
              child: const Text('Choose a color'),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Pick a color')),
      body: ListView(
        children: [
          for (String color in ['Red', 'Green', 'Blue'])
            ListTile(
              title: Text(color),
              onTap: () {
                Navigator.pop(context);
              },
            ),
        ],
      ),
    );
  }
}
quiz icon自我测试

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

列表和屏幕中的所有课

自己练习: Flutter 在线编译器