Kodokon kodokon.com

การนำทางระหว่างหน้าจอด้วย Navigator

push และ pop หน้าจอด้วย Navigator.push และ pop ส่งข้อมูลผ่านคอนสตรักเตอร์ และรับผลลัพธ์กลับมาเมื่อหน้าจอปิดลง

8 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

Flutter จัดการหน้าจอของคุณในรูปแบบ สแตก โดย Navigator.push จะวางหน้าจอใหม่ไว้ด้านบน ส่วน Navigator.pop จะเอาหน้าจอบนสุดออกและเผยหน้าจอก่อนหน้าออกมา แต่ละหน้าจอคือ รูต (route) และ MaterialPageRoute จะให้ทรานซิชันแบบเนทีฟของแพลตฟอร์ม ปุ่มย้อนกลับของ Android จะเรียก pop ให้คุณเอง โดยไม่ต้องเขียนโค้ดสักบรรทัด

DART
import 'package:flutter/material.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Home')),
      body: Center(
        child: FilledButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) {
                  return const DetailScreen(
                    productName: 'Headphones',
                  );
                },
              ),
            );
          },
          child: const Text('View product'),
        ),
      ),
    );
  }
}
push จะดัน DetailScreen (ที่นิยามไว้ด้านล่าง) ขึ้นไปไว้บนหน้าจอปัจจุบัน

การส่งข้อมูลไปยังหน้าจอถัดไปไม่มีกลไกวิเศษใด ๆ หน้าจอปลายทางก็เป็นวิดเจ็ตเหมือนตัวอื่น ๆ และมันรับข้อมูลของมัน ผ่านคอนสตรักเตอร์ ซึ่งมีการระบุชนิด ชัดเจน และคอมไพเลอร์จะจับได้ทันทีหากมีฟิลด์ใดขาดหายไป สังเกตว่า AppBar ของหน้าจอที่ถูก push จะแสดงปุ่มย้อนกลับให้เองโดยที่คุณไม่ต้องเขียนอะไรเลย

DART
import 'package:flutter/material.dart';

class DetailScreen extends StatelessWidget {
  const DetailScreen({
    super.key,
    required this.productName,
  });

  final String productName;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(productName)),
      body: Center(
        child: FilledButton(
          onPressed: () {
            Navigator.pop(context, true);
          },
          child: const Text('Add to cart'),
        ),
      ),
    );
  }
}
pop ปิดหน้าจอและส่งค่ากลับไปยังจุดที่เรียก

Navigator.push คืนค่าเป็น Future ที่จะเสร็จสมบูรณ์เมื่อหน้าจอถูกปิด พร้อมกับค่าที่ส่งให้ pop ดังนั้นคุณจึงสามารถ รอผลลัพธ์ (await) ของหน้าจอได้ ไม่ว่าจะเป็นการยืนยัน ไอเทมที่เลือกจากรายการ หรือฟอร์มที่กรอกเสร็จ ชนิดเจเนอริก push<bool> ช่วยบอกว่าคุณคาดหวังจะได้อะไรกลับมา

DART
import 'package:flutter/material.dart';

Future<void> openDetail(BuildContext context) async {
  final added = await Navigator.push<bool>(
    context,
    MaterialPageRoute<bool>(
      builder: (context) {
        return const DetailScreen(
          productName: 'Headphones',
        );
      },
    ),
  );
  if (!context.mounted) return;
  final message = (added ?? false)
      ? 'Product added to cart'
      : 'No product added';
  ScaffoldMessenger.of(context).showSnackBar(
    SnackBar(content: Text(message)),
  );
}
Future ของ push จะเสร็จสมบูรณ์เมื่อหน้าจอปิดลง

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. Navigator จัดระเบียบหน้าจออย่างไร?
    • แบบคิว คือเข้าก่อน แสดงก่อน
    • แบบสแตก คือหน้าจอที่ push เข้าไปล่าสุดจะถูกแสดงอยู่บนสุด
    • แบบทรีของวิดเจ็ตที่ขนานกัน
    • แบบตารางกริดของหน้าจอ
  2. วิธีที่เป็นสำนวนนิยมในการส่งข้อมูลไปยังหน้าจอถัดไปคืออะไร?
    • ผ่านตัวแปรโกลบอล
    • ผ่านคอนสตรักเตอร์ของวิดเจ็ตปลายทาง
    • โดยการเขียนลงดิสก์
    • Navigator ไม่อนุญาตให้ส่งข้อมูล
  3. Navigator.pop(context, true) ทำอะไร?
    • มันเปิดหน้าจอใหม่ชื่อ "true"
    • มันปิดทุกหน้าจอในสแตก
    • มันปิดหน้าจอปัจจุบันและส่ง true กลับไปยัง push ที่กำลังรออยู่