Giờ làm việc

T2 - T7 8h30 - 18h00

Liên hệ

 

Di chuyển giữa các màn hình, truyền dữ liệu bằng Navigator và Route trong Flutter

Trong quá trình phát triển ứng dụng Flutter, một trong những kỹ thuật cơ bản nhưng rất quan trọng là di chuyển giữa các màn hình (navigation). Flutter cung cấp một hệ thống điều hướng mạnh mẽ dựa trên NavigatorRoute, cho phép bạn chuyển màn hình, truyền dữ liệu qua lại và quản lý hành trình người dùng trong ứng dụng một cách hiệu quả.

Bài chia sẻ dưới đây do Thầy Lê Hồng Duy – Giảng viên CNTT, Thạc sĩ CNTT Đại học Bách khoa Hà Nội – biên soạn theo video demo (dưới đây).
Thầy Duy là chuyên gia lập trình Web, Mobileứng dụng AI, hiện chia sẻ kiến thức qua kênh YouTubeGitHub.
Sau đây là hướng dẫn chi tiết các bước thực hiện, giúp bạn nhanh chóng nắm vững và áp dụng được kỹ thuật điều hướng trong Flutter.

1. Navigator và Route là gì?

Navigator

Flutter Route and Navigation - YouTube

Navigator là một widget đặc biệt trong Flutter, quản lý ngăn xếp (stack) các màn hình. Khi bạn mở một màn hình mới, màn hình đó được đẩy (push) vào ngăn xếp; khi bạn quay lại, nó được loại bỏ (pop).

Route

Mọi thứ bạn cần biết về Route Transition của Flutter | 200Lab Blog

Route đại diện cho một màn hình trong ứng dụng. Trong Flutter, màn hình thực chất là một widget (thường là StatelessWidget hoặc StatefulWidget) và mỗi lần điều hướng là bạn đang đẩy một Route mới vào Navigator.

2. Điều hướng cơ bản giữa hai màn hình

Giả sử bạn có hai màn hình: HomeScreenDetailScreen.

a. Định nghĩa các màn hình

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => DetailScreen()),
            );
          },
          child: Text('Đi đến Detail'),
        ),
      ),
    );
  }
}

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Detail')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context); // Quay về HomeScreen
          },
          child: Text('Quay lại'),
        ),
      ),
    );
  }
}

3. Truyền dữ liệu giữa các màn hình

a. Truyền dữ liệu từ màn hình A → B

Bạn có thể truyền dữ liệu bằng cách truyền thông qua constructor của màn hình đích.

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => DetailScreen(data: 'Hello from Home'),
  ),
);
class DetailScreen extends StatelessWidget {
  final String data;

  const DetailScreen({Key? key, required this.data}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text('Dữ liệu nhận được: $data')),
    );
  }
}

4. Nhận dữ liệu trả về khi quay lại

Flutter cho phép bạn nhận dữ liệu trả về từ một màn hình sau khi pop.

a. Truyền dữ liệu khi pop

Navigator.pop(context, 'Giá trị trả về');

b. Nhận dữ liệu ở màn hình trước

final result = await Navigator.push(
  context,
  MaterialPageRoute(builder: (context) => InputScreen()),
);
print('Dữ liệu trả về: $result');

c. Màn hình nhập dữ liệu và trả về

class InputScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context, 'Dữ liệu đã nhập');
          },
          child: Text('Trả dữ liệu về'),
        ),
      ),
    );
  }
}

5. Named Route – Điều hướng bằng tên

Khi ứng dụng có nhiều màn hình, Flutter cho phép bạn quản lý route bằng cách đặt tên rõ ràng.

a. Khai báo trong MaterialApp

MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => HomeScreen(),
    '/detail': (context) => DetailScreen(),
  },
);

b. Điều hướng đến màn hình qua tên

Navigator.pushNamed(context, '/detail');

c. Truyền và nhận arguments trong Named Route

Truyền dữ liệu:

Navigator.pushNamed(
  context,
  '/detail',
  arguments: 'Hello Named Route',
);

Nhận dữ liệu:

class DetailScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as String;

    return Scaffold(
      body: Center(child: Text('Nhận qua arguments: $args')),
    );
  }
}

6. onGenerateRoute – Xử lý route động

Flutter onGenerateRoute Example

Khi bạn muốn xử lý các route linh hoạt hơn, ví dụ truyền một đối tượng phức tạp, onGenerateRoute là công cụ mạnh mẽ.

Cấu hình:

MaterialApp(
  onGenerateRoute: (settings) {
    if (settings.name == '/detail') {
      final String data = settings.arguments as String;
      return MaterialPageRoute(
        builder: (context) => DetailScreen(data: data),
      );
    }
    return null;
  },
)

7. So sánh các cách điều hướng

Cách điều hướngĐặc điểmƯu điểmNhược điểm
push / popThủ côngĐơn giản, trực quanKhông kiểm soát tập trung
Named Route (routes)Cấu hình sẵnGọn, quản lý dễHạn chế truyền dữ liệu phức tạp
onGenerateRouteTùy biến caoTruyền object linh hoạtCần xử lý logic nhiều hơn

Kết luận

Hệ thống điều hướng của Flutter cho phép bạn:

  • Di chuyển mượt giữa các màn hình.
  • Truyền dữ liệu hai chiều.
  • Quản lý đường đi của người dùng trong ứng dụng một cách logic và rõ ràng.

Việc nắm chắc kiến thức về Navigator, Route, push/pop, và Named Route sẽ giúp bạn xây dựng các ứng dụng có trải nghiệm người dùng mượt mà và dễ mở rộng trong tương lai. Tất cả kiến thức này đều có trong khóa học “Lập trình Flutter toàn tập” tại CodeFresher, được thiết kế dành cho người mới bắt đầu hoặc đã có nền tảng và muốn đi xa hơn với Flutter theo cách bài bản, thực chiến và dễ hiểu.

Địa chỉ: Trung tâm CodeFresher – số 104 Hoàng Ngân, Cầu Giấy, Hà Nội.
Hotline: 0813188668 – 0332026803 (zalo / call)

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

Gọi ngay