Navigator: nó là gì, quản lý màn hình trong Flutter

Tác giả: IT Sectr Đã đăng: 2026-07-02 Thời gian đọc: 9 phút

Navigator là widget quản lý điều hướng trong Flutter, quản lý một ngăn xếp các đối tượng Route để di chuyển giữa các màn hình thông qua các phương thức push, pop, pushReplacement và pushNamed. Không giống như việc thay thế widget trực tiếp qua State, Navigator hoạt động ở cấp độ toàn bộ màn hình: nó lưu trữ lịch sử chuyển tiếp và hỗ trợ hoạt ảnh dành riêng cho nền tảng. Theo Tài liệu tham khảo API Flutter (2026), Navigator 2.0 (Router) cung cấp quản lý điều hướng khai báo cho các tình huống phức tạp với liên kết sâu và thiết kế thích ứng. Trong một ứng dụng điển hình, Navigator đảm bảo hành vi chính xác của nút Quay lại trên Android và cử chỉ vuốt trên iOS.

Những điểm chính

  • Navigator — trình quản lý điều hướng kiểm soát ngăn xếp các tuyến đường thông qua các phương thức push, pop, pushNamed, pushReplacement và pushAndRemoveUntil
  • Ngăn xếp tuyến đường — Navigator lưu trữ các màn hình trong ngăn xếp LIFO: mỗi push thêm một màn hình lên trên, pop xóa màn hình trên cùng
  • pushNamed — điều hướng theo các tuyến đường được đặt tên được định nghĩa trong MaterialApp.routes hoặc onGenerateRoute
  • pushReplacement — thay thế màn hình hiện tại bằng màn hình mới mà không thể quay lại (ví dụ: sau khi đăng nhập)
  • Navigator 2.0 — API khai báo với Router, RouterDelegate và RouteInformationParser cho điều hướng web và máy tính

Navigator trong Flutter là gì

Navigator là một widget quản lý ngăn xếp các đối tượng Route, triển khai điều hướng màn hình trong ứng dụng Flutter. Mỗi lần gọi push đặt một Route mới lên đỉnh ngăn xếp, pop xóa Route trên cùng và quay lại màn hình trước đó. MaterialApp tự động tạo Navigator cho toàn bộ ứng dụng, làm cho nó có thể truy cập được qua Navigator.of(context).

Không giống như StatefulWidget, nơi việc thay thế nội dung diễn ra qua setState bên trong một widget duy nhất, Navigator hoạt động với toàn bộ màn hình có vòng đời riêng. Mỗi Route trong ngăn xếp là một trạng thái biệt lập với BuildContext riêng, ngăn ngừa rò rỉ bộ nhớ và đơn giản hóa việc quản lý phụ thuộc. Khi pop được gọi, Route không sử dụng sẽ bị hủy, giải phóng tài nguyên.

Theo Hướng dẫn điều hướng Flutter (2026), Navigator đã phát triển từ API mệnh lệnh (Navigator 1.0) sang khai báo (Navigator 2.0). Navigator 1.0 sử dụng các phương thức push/pop trực tiếp, thuận tiện cho các tình huống đơn giản. Navigator 2.0 (Router) phù hợp cho các ứng dụng có liên kết sâu, điều hướng thích ứng và định tuyến web.

Cách Navigator hoạt động bên trong

Bên trong, Navigator sử dụng Overlay — một widget đặc biệt hiển thị các Route chồng lên nhau. Mỗi Route tạo vị trí riêng trong Overlay với chỉ số z tương ứng với độ sâu của nó trong ngăn xếp. Điều này giải thích tại sao khi gọi push, màn hình mới hoạt ảnh lên trên màn hình trước, và khi gọi pop, màn hình trước đã sẵn sàng hiển thị: nó không bị hủy mà vẫn ở trong Overlay bên dưới màn hình mới.

Đối với hoạt ảnh chuyển tiếp, Navigator sử dụng PageTransitionsTheme, có thể được ghi đè trong ThemeData. Hoạt ảnh dành riêng cho nền tảng được thiết lập qua CupertinoPageRoute cho iOS (trượt từ phải) và MaterialPageRoute cho Android (trượt từ dưới lên). Navigator tự động chọn hoạt ảnh chính xác khi sử dụng PlatformRoute.

Navigator cung cấp một tập hợp các phương thức để quản lý ngăn xếp Route. Mỗi phương thức giải quyết một tác vụ điều hướng cụ thể — từ chuyển tiếp đơn giản đến thay thế hoàn toàn lịch sử màn hình. Hãy xem xét các phương thức chính với ví dụ sử dụng.

Phương thứcMô tảTình huống sử dụng
pushThêm một Route lên đỉnh ngăn xếpĐiều hướng đến màn hình mới có thể quay lại
popXóa Route trên cùng khỏi ngăn xếpQuay lại màn hình trước
pushReplacementThay thế Route hiện tại bằng Route mớiSau khi đăng nhập — màn hình đăng nhập được thay thế bằng màn hình chính
pushAndRemoveUntilThêm Route và xóa các Route trước cho đến khi đạt điều kiệnĐi đến màn hình chính và xóa lịch sử
popUntilXóa các Route khỏi ngăn xếp cho đến khi đạt điều kiệnQuay lại một màn hình cụ thể trong lịch sử
maybePopChỉ gọi pop nếu ngăn xếp chứa >1 RouteNgăn đóng ứng dụng khi vô tình nhấn nút Quay lại

Push và Pop: các thao tác cơ bản

Phương thức push nhận một Route và trả về một Future với kết quả được truyền trong quá trình pop. Điều này cho phép nhận dữ liệu từ màn hình đã điều hướng đến. Ví dụ, màn hình chọn ngày có thể trả về DateTime qua Navigator.pop(context, selectedDate). Phương thức pop không có đối số trả về null, có đối số — truyền giá trị cho màn hình gọi.

PushReplacement: thay thế màn hình

pushReplacement thay thế Route hiện tại bằng Route mới, xóa route hiện tại khỏi ngăn xếp. Điều này rất quan trọng cho các tình huống mà người dùng không được phép quay lại màn hình trước. Một ví dụ điển hình — màn hình đăng nhập: sau khi đăng nhập thành công, màn hình hiện tại được thay thế bằng màn hình chính và nút Quay lại không trở về biểu mẫu đăng nhập.

Các tuyến đường được đặt tên và onGenerateRoute

Navigator hỗ trợ điều hướng theo các tuyến đường được đặt tên thông qua phương thức pushNamed. Thay vì tạo Route trực tiếp, nhà phát triển chỉ định một định danh chuỗi và Navigator tự động tạo Route dựa trên cấu hình trong MaterialApp. Điều này đơn giản hóa mã và tập trung định nghĩa tuyến đường tại một nơi.

Các tuyến đường được đặt tên được định nghĩa thông qua thuộc tính routes trong MaterialApp, nơi mỗi khóa là một chuỗi đường dẫn và giá trị là một hàm trả về Widget. Đối với các tuyến đường động (có tham số), onGenerateRoute được sử dụng — một callback nhận RouteSettings và trả về Route. Điều này cho phép truyền đối số qua tham số arguments và triển khai điều hướng sâu.

Theo Flutter Cookbook (2026), việc truyền đối số qua pushNamed được thực hiện với tham số arguments: Object?. Màn hình nhận trích xuất đối số qua ModalRoute.of(context)!.settings.arguments, cung cấp truyền dữ liệu an toàn kiểu mà không cần biến toàn cục hay InheritedWidget.

Xử lý các tuyến đường không xác định

Thuộc tính onUnknownRoute trong MaterialApp xử lý các trường hợp pushNamed được gọi với tuyến đường không tồn tại. Điều này hữu ích để hiển thị màn hình 404 hoặc chuyển hướng đến trang chủ. Kết hợp với onGenerateRoute, nó đảm bảo bao phủ đầy đủ tất cả các tình huống điều hướng có thể.

Navigator 2.0 (còn được gọi là API Router) là một cách tiếp cận khai báo đối với điều hướng được giới thiệu trong Flutter 2.0. Không giống như Navigator 1.0 mệnh lệnh, nơi nhà phát triển gọi push/pop, Router quản lý điều hướng thông qua trạng thái, tự động đồng bộ hóa URL trình duyệt với màn hình hiện tại. Điều này đặc biệt quan trọng đối với các ứng dụng web và phiên bản máy tính.

Kiến trúc Navigator 2.0 bao gồm ba thành phần chính: RouteInformationParser phân tích URL thành cấu hình tuyến đường, RouterDelegate chuyển đổi cấu hình thành danh sách các Route, và BackButtonDispatcher xử lý nút Quay lại của hệ thống. Kiến trúc này làm cho điều hướng hoàn toàn có thể dự đoán và kiểm thử được.

Để đơn giản hóa công việc với Navigator 2.0, có các gói wrapper: go_router (được Google khuyến nghị), auto_routebeamer. go_router cung cấp một DSL khai báo để định nghĩa các tuyến đường với hỗ trợ điều hướng lồng nhau, chuyển hướng và liên kết sâu mà không cần triển khai RouterDelegate thủ công. Theo pub.dev (2026), go_router được sử dụng trong 35% các dự án Flutter mới ưa thích cách tiếp cận khai báo.

Hãy xem xét một ví dụ về Navigator với các tuyến đường được đặt tên và truyền dữ liệu giữa các màn hình. Mã này minh họa màn hình danh sách sản phẩm, chuyển tiếp đến màn hình chi tiết và quay lại với kết quả.

dart
// Route configuration in MaterialApp
MaterialApp(
  initialRoute: '/',
  onGenerateRoute: (RouteSettings settings) {
    if (settings.name == '/') {
      return MaterialPageRoute(
        builder: (context) => const ProductListPage(),
      );
    }
    if (settings.name == '/product') {
      final productId = settings.arguments as String;
      return MaterialPageRoute(
        builder: (context) => ProductDetailPage(productId: productId),
      );
    }
    return MaterialPageRoute(
      builder: (context) => const NotFoundPage(),
    );
  },
)

// Navigation with data passing
final result = await Navigator.pushNamed(
  context,
  '/product',
  arguments: 'product_42',
);

// Getting data on the receiving screen
final args = ModalRoute.of(context)!.settings.arguments as String;

// Replace screen after login
Navigator.pushReplacementNamed(context, '/home');

// Clear stack to main screen
Navigator.pushNamedAndRemoveUntil(
  context,
  '/home',
  (route) => false,
);

Trong ví dụ, Navigator.pushNamed truyền ID sản phẩm đến màn hình chi tiết. Khi quay lại qua Navigator.pop(context, updatedProduct), màn hình gọi nhận được dữ liệu đã cập nhật trong biến result. pushReplacementNamed thay thế màn hình hiện tại sau khi ủy quyền, và pushNamedAndRemoveUntil với điều kiện (route) => false xóa sạch hoàn toàn ngăn xếp, ngăn chặn việc điều hướng trở lại các màn hình trước.

Các câu hỏi thường gặp

Sự khác biệt giữa Navigator 1.0 và Navigator 2.0 là gì?

Navigator 1.0 — API mệnh lệnh với các phương thức push và pop, thuận tiện cho các ứng dụng di động đơn giản. Navigator 2.0 — API khai báo qua Router, RouterDelegate và RouteInformationParser, cần thiết cho các ứng dụng web có định tuyến URL, liên kết sâu và điều hướng thích ứng. Đối với các dự án thực tế, go_router được khuyến nghị như một wrapper đơn giản hóa trên Navigator 2.0.

Làm thế nào để truyền dữ liệu giữa các màn hình qua Navigator?

Dữ liệu được truyền qua tham số arguments trong pushNamed hoặc trực tiếp qua hàm tạo Route. Trên màn hình nhận, dữ liệu được trích xuất qua ModalRoute.of(context)!.settings.arguments. Để trả về dữ liệu, hãy sử dụng Navigator.pop(context, result) — màn hình gọi sẽ nhận kết quả dưới dạng giá trị Future được trả về từ push.

Tại sao nút Quay lại không trở về màn hình trước?

Điều này xảy ra nếu màn hình hiện tại được mở qua pushReplacement, thao tác này xóa Route trước khỏi ngăn xếp. Trong trường hợp này, không có lịch sử điều hướng và nút Quay lại đóng ứng dụng. Để quay lại, hãy sử dụng push thông thường thay vì pushReplacement. Cũng kiểm tra xem lệnh gọi Navigator.pop có được xử lý chính xác trên màn hình hiện tại không.

Làm thế nào để ngăn chặn việc quay lại màn hình trước?

Sử dụng pushReplacement để thay thế màn hình hiện tại bằng màn hình mới — màn hình trước bị xóa khỏi ngăn xếp và không thể quay lại. Để xóa sạch hoàn toàn lịch sử, hãy sử dụng pushAndRemoveUntil với điều kiện (route) => false. Thay vào đó, bạn có thể ghi đè WillPopScope (không dùng nữa) hoặc PopScope để chặn nút Quay lại của hệ thống.

go_router là gì và khi nào nên sử dụng nó?

go_router là một gói điều hướng khai báo của Google được xây dựng trên Navigator 2.0. Nó cung cấp một DSL đơn giản để định nghĩa các tuyến đường với hỗ trợ lồng nhau, chuyển hướng, liên kết sâu và ShellRoute cho BottomNavigationBar. Sử dụng go_router cho các dự án mới, đặc biệt nếu cần hỗ trợ web hoặc các mẫu điều hướng phức tạp với tuyến đường được bảo vệ.

Tóm tắt

  • Navigator — trình quản lý điều hướng Flutter kiểm soát ngăn xếp Route với các phương thức push, pop, pushReplacement và pushAndRemoveUntil
  • Ngăn xếp LIFO — mỗi push thêm một Route lên trên, pop xóa trên cùng; ngăn xếp lưu trữ lịch sử chuyển tiếp theo nguyên tắc last-in-first-out
  • pushReplacement — thay thế màn hình hiện tại mà không thể quay lại, rất quan trọng cho các tình huống đăng nhập và giới thiệu
  • Các tuyến đường được đặt tên — pushNamed với RouteSettings và onGenerateRoute để định nghĩa tuyến đường tập trung với truyền đối số
  • Navigator 2.0 — điều hướng khai báo qua Router, RouterDelegate và RouteInformationParser cho liên kết sâu web
  • go_router — wrapper được Google khuyến nghị trên Navigator 2.0 với DSL đơn giản và hỗ trợ ShellRoute
  • Truyền dữ liệu — qua arguments trong pushNamed và trả về kết quả qua Future từ push bằng Navigator.pop(context, value)

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm