
Chào các em, lại là Creyt đây! Hôm nay chúng ta sẽ mổ xẻ một 'công cụ' nhỏ mà có võ trong Flutter, đó là MaterialBanner. Các em cứ hình dung thế này, trong một căn nhà, có những lúc ta cần dán một cái 'post-it note' ngay cửa tủ lạnh để nhắc nhở những việc quan trọng: 'Hôm nay có sữa hết hạn!', 'Nhớ đóng tiền điện nhé!'. Nó ở đó, ngay tầm mắt, không la hét inh ỏi như chuông báo cháy (AlertDialog), cũng không thoáng qua nhanh như một lời thì thầm (SnackBar). Nó cứ lẳng lặng ở đó, cho đến khi ta đọc và hành động. MaterialBanner chính là cái 'post-it note' ấy trong thế giới ứng dụng của chúng ta.
Nói một cách hàn lâm hơn, MaterialBanner là một widget UI trong Flutter, được thiết kế theo Material Design, dùng để hiển thị các thông báo quan trọng, mang tính chất hệ thống hoặc ứng dụng, mà không làm gián đoạn luồng công việc hiện tại của người dùng. Nó xuất hiện ở phía trên cùng của Scaffold, và có thể chứa nội dung, biểu tượng (leading icon) và các hành động (actions) để người dùng tương tác. Điểm đặc biệt của nó là nó không tự động biến mất sau một thời gian ngắn như SnackBar, mà cần được người dùng hoặc hệ thống chủ động đóng lại.
Code Ví Dụ Minh Hoạ
Giờ thì, lý thuyết suông thì chán òm. Chúng ta phải 'xắn tay áo' vào code mới thấy nó 'ngon' cỡ nào. Để dùng MaterialBanner, chúng ta sẽ cần đến 'anh quản gia' của màn hình, đó là ScaffoldMessenger.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MaterialBanner Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('MaterialBanner Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
// Hiển thị MaterialBanner
ScaffoldMessenger.of(context).showMaterialBanner(
MaterialBanner(
content: const Text('Mạng của bạn đang ngoại tuyến. Dữ liệu có thể không được cập nhật.'),
leading: const Icon(Icons.signal_wifi_off, color: Colors.white),
backgroundColor: Colors.redAccent,
actions: <Widget>[
TextButton(
onPressed: () {
// Đóng MaterialBanner hiện tại
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
},
child: const Text('ĐÓNG', style: TextStyle(color: Colors.white)),
),
TextButton(
onPressed: () {
// Ví dụ: thử kết nối lại
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Đang thử kết nối lại...'))
);
},
child: const Text('THỬ LẠI', style: TextStyle(color: Colors.white)),
),
],
),
);
},
child: const Text('Hiển thị MaterialBanner'),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Đóng MaterialBanner nếu có
ScaffoldMessenger.of(context).hideCurrentMaterialBanner();
},
child: const Text('Đóng MaterialBanner'),
),
],
),
),
);
}
}

Mẹo Vặt và Best Practices (Thực hành tốt nhất)
Ổn rồi, code chạy ngon lành cành đào rồi. Nhưng để dùng nó 'chuẩn bài', không biến ứng dụng của mình thành 'bãi rác thông báo', các em cần ghi nhớ vài điều Creyt dặn dò:
- Dùng đúng việc:
MaterialBannersinh ra là để thông báo những thứ quan trọng, nhưng KHÔNG CẦN NGƯỜI DÙNG PHẢI DỪNG LẠI NGAY LẬP TỨC để xử lý. Ví dụ: 'Mạng yếu', 'Cập nhật ứng dụng mới', 'Dữ liệu đã được lưu thành công nhưng có thể chưa đồng bộ'. Tuyệt đối không dùng nó để hỏi 'Bạn có chắc muốn xóa?' – cái đó là việc củaAlertDialog. - Có lối thoát: Luôn cung cấp ít nhất một hành động để người dùng có thể đóng
MaterialBanner. Không ai thích bị mắc kẹt với một thông báo cứ lù lù trên đầu cả. - Ngắn gọn, súc tích: Nội dung của
MaterialBannernên ngắn gọn, dễ hiểu. Đừng viết một bài văn trong đó. - Biểu tượng (Leading Icon): Thêm một cái icon phù hợp sẽ giúp thông báo trở nên trực quan và đẹp mắt hơn rất nhiều. Ví dụ: icon wifi gạch chéo cho thông báo mất mạng.
- Quản lý qua
ScaffoldMessenger: Luôn nhớ rằngScaffoldMessengerlà "người gác cổng" duy nhất choMaterialBanner. DùngScaffoldMessenger.of(context).showMaterialBanner()để hiển thị vàhideCurrentMaterialBanner()để ẩn đi.
Ứng Dụng Thực Tế
Vậy thì, trong thế giới thực, các em có thể thấy những 'ông lớn' nào đang dùng cái 'post-it note' này dưới một hình thức nào đó? Dù không phải lúc nào cũng là MaterialBanner đúng nghĩa của Flutter, nhưng cái ý tưởng về một banner thông báo không chặn tương tác thì phổ biến vô cùng:
- Google Drive/Docs/Sheets: Khi bạn làm việc ngoại tuyến, sẽ có một banner xuất hiện ở trên cùng thông báo "Offline mode enabled" hoặc "Document saved offline". Khi có mạng lại, nó có thể thông báo "All changes saved to cloud".
- Ứng dụng ngân hàng/tài chính: Đôi khi sẽ có banner thông báo về các chương trình khuyến mãi, cập nhật bảo mật, hoặc thông báo hệ thống đang bảo trì.
- Ứng dụng tin tức/truyền thông: "New articles available", "Bạn đang đọc phiên bản cũ, vuốt xuống để cập nhật tin mới."
- Ứng dụng giao hàng: "Đơn hàng của bạn đang được xử lý," "Tài xế đang đến." (Mặc dù đôi khi là SnackBar, nhưng ý tưởng thông báo trạng thái không chặn là tương tự).
- Ứng dụng email: "Đang đồng bộ thư..." hoặc "Không thể kết nối với máy chủ."
Tóm lại, MaterialBanner là một công cụ tuyệt vời để giữ cho người dùng được thông tin mà không làm họ khó chịu. Hãy dùng nó một cách khôn ngoan, các em nhé!
Thuộc Series: Flutter
Bài giảng này được tự động xuất bản ngẫu nhiên từ thư viện kiến thức. Đừng quên đón xem các Từ khoá Hướng Dẫn tiếp theo nhé!