
Chào mừng các bạn đến với buổi học hôm nay, nơi chúng ta sẽ cùng "mổ xẻ" một "chi tiết máy" vô cùng thú vị trong thế giới Flutter: BottomAppBar. Nghe tên có vẻ khô khan, nhưng tin tôi đi, đây chính là "cánh tay đắc lực" giúp ứng dụng của bạn trở nên chuyên nghiệp và thân thiện hơn rất nhiều.
1. BottomAppBar là gì và để làm gì?
Hãy hình dung thế này: Khi bạn bước vào một căn bếp hiện đại, mọi dụng cụ quan trọng như dao, thớt, gia vị... đều được đặt gọn gàng, dễ lấy ở những vị trí chiến lược, thường là ngay tầm tay hoặc dưới quầy bếp. BottomAppBar trong Flutter cũng chính là "khu vực chiến lược" đó, nhưng là ở phần dưới cùng của màn hình ứng dụng của bạn.
Nó là một widget của Material Design, được thiết kế để cung cấp một khu vực chức năng nằm sát đáy màn hình. Khác với BottomNavigationBar (cái "bảng điều khiển" để chuyển trang), BottomAppBar tập trung vào việc hiển thị các hành động chính yếu hoặc các nút điều khiển nhanh. Nó thường được sử dụng để:
- Hiển thị các nút hành động (IconButton): Ví dụ như nút "tìm kiếm", "chia sẻ", "cài đặt nhanh"... những thứ bạn muốn người dùng truy cập chỉ với một chạm.
- Tích hợp FloatingActionButton (FAB): Đây là "bộ đôi hoàn hảo"!
BottomAppBarthường là nơi để "neo" mộtFloatingActionButton(nút hành động nổi bật, thường là hành động chính của màn hình) vào, tạo ra một hiệu ứng thị giác độc đáo và thu hút sự chú ý. Bạn có thể thấy nó tạo ra một "vết cắt" (notch) hoặc "cầu nối" để FAB nằm gọn gàng, đẹp mắt.
Tóm lại, BottomAppBar không chỉ là một thanh đơn thuần, nó là một "sân khấu nhỏ" để bạn trình diễn những chức năng quan trọng nhất, giúp người dùng thao tác nhanh gọn và hiệu quả, giống như việc bạn có một chiếc điều khiển từ xa đa năng luôn nằm ngay ngắn trong tầm tay.

2. Code Ví Dụ Minh Hoạ Rõ Ràng
Để bạn dễ hình dung, chúng ta sẽ xây dựng một ví dụ đơn giản với BottomAppBar chứa một vài IconButton và một FloatingActionButton được neo vào nó.
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: 'BottomAppBar Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _message = 'Chào mừng bạn!';
void _showSnackbar(String action) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Bạn vừa nhấn: $action'),
duration: const Duration(milliseconds: 800),
),
);
setState(() {
_message = 'Hành động: $action';
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BottomAppBar Ngầu Lòi'),
),
body: Center(
child: Text(
_message,
style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => _showSnackbar('FAB - Thêm mới'),
tooltip: 'Thêm mới',
child: const Icon(Icons.add),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
bottomNavigationBar: BottomAppBar(
shape: const CircularNotchedRectangle(), // Tạo vết lõm cho FAB
color: Colors.blueAccent, // Màu nền của BottomAppBar
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
icon: const Icon(Icons.home, color: Colors.white),
tooltip: 'Trang chủ',
onPressed: () => _showSnackbar('Trang chủ'),
),
IconButton(
icon: const Icon(Icons.search, color: Colors.white),
tooltip: 'Tìm kiếm',
onPressed: () => _showSnackbar('Tìm kiếm'),
),
// Khoảng trống cho FAB nếu dùng centerDocked
const SizedBox(width: 48),
IconButton(
icon: const Icon(Icons.favorite, color: Colors.white),
tooltip: 'Yêu thích',
onPressed: () => _showSnackbar('Yêu thích'),
),
IconButton(
icon: const Icon(Icons.settings, color: Colors.white),
tooltip: 'Cài đặt',
onPressed: () => _showSnackbar('Cài đặt'),
),
],
),
),
);
}
}
Giải thích nhanh:
Scaffoldlà "bộ khung" của màn hình.BottomAppBarlà một thuộc tính của nó.floatingActionButtonvàfloatingActionButtonLocationlà hai thuộc tính quan trọng để FAB "hợp tác" vớiBottomAppBar.FloatingActionButtonLocation.centerDockedsẽ neo FAB vào giữaBottomAppBar.
BottomAppBarcóshape: const CircularNotchedRectangle()để tạo ra "vết lõm" tròn, nơi FAB có thể "neo" vào, tạo hiệu ứng thị giác rất đẹp.- Bên trong
childcủaBottomAppBar, chúng ta thường dùngRowđể sắp xếp cácIconButton. SizedBox(width: 48)(hoặc một giá trị tương đương) được dùng để tạo khoảng trống, tránh việc cácIconButtonche mất FAB khi nó được neo vào giữa.
3. Mẹo Vặt (Best Practices) Để Ghi Nhớ và Dùng Thực Tế
Là một "kiến trúc sư" phần mềm, bạn cần biết cách đặt "nội thất" sao cho vừa đẹp, vừa tiện dụng. Dưới đây là vài lời khuyên vàng:
- "Đừng nhầm lẫn với BottomNavigationBar!": Đây là lỗi kinh điển.
BottomAppBarkhông phải để chuyển đổi giữa các màn hình chính (Home, Explore, Profile...). Nhiệm vụ đó là củaBottomNavigationBar.BottomAppBarsinh ra để chứa hành động, cònBottomNavigationBarlà để điều hướng. Hãy nhớ kỹ "hành động" vs "điều hướng"! - "FAB là bạn thân của BottomAppBar": Hầu hết các trường hợp, khi bạn dùng
BottomAppBar, bạn sẽ muốn có mộtFloatingActionButtonđi kèm. Chúng là một cặp bài trùng, tạo nên một điểm nhấn UI/UX rất mạnh mẽ. Hãy tận dụng thuộc tínhshape(ví dụ:CircularNotchedRectangle) vàfloatingActionButtonLocation(centerDocked,endDocked) để tạo hiệu ứng neo FAB độc đáo. - "Ít là nhiều": Đừng biến
BottomAppBarthành một "chợ trời" đầy rẫy icon. Chỉ đặt những hành động thực sự quan trọng và thường xuyên sử dụng. Quá nhiều nút sẽ gây rối mắt và khó sử dụng. - "Cá nhân hóa để nổi bật":
BottomAppBarcó thể tùy chỉnh màu sắc (color), độ cao (elevation), hình dạng (shape). Đừng ngại thử nghiệm để nó phù hợp với phong cách thương hiệu ứng dụng của bạn. MộtBottomAppBarđược thiết kế tốt có thể tạo nên dấu ấn riêng. - "Kiểm tra trên nhiều thiết bị": Luôn kiểm tra giao diện của bạn trên các kích thước màn hình khác nhau để đảm bảo
BottomAppBarvà các nút bên trong hiển thị đúng và dễ tương tác, tránh tình trạng bị tràn hoặc quá nhỏ.
4. Ứng Dụng Thực Tế Các Website/App Đã Ứng Dụng
Bạn có thể thấy ý tưởng về một thanh hành động ở dưới cùng màn hình trong nhiều ứng dụng quen thuộc, đặc biệt là những ứng dụng tập trung vào việc tạo nội dung hoặc thực hiện hành động chính:
- Google Keep: Mặc dù không phải lúc nào cũng là
BottomAppBarthuần túy, nhưng ý tưởng về một thanh ở dưới cùng với nút "Thêm ghi chú mới" (thường là FAB) là rất rõ ràng. Nó cho phép người dùng nhanh chóng tạo ghi chú mà không cần tìm kiếm menu. - Gmail (phiên bản cũ hoặc một số layout cụ thể): Nút "Soạn thư mới" (Compose) thường là một FAB nổi bật, và đôi khi nó được neo vào một thanh tương tự
BottomAppBarở dưới cùng, đặc biệt trên các thiết bị màn hình nhỏ hơn để tối ưu không gian. - Ứng dụng ghi chú hoặc quản lý công việc (Todoist, Trello): Các ứng dụng này thường có nút "Thêm nhiệm vụ/ghi chú mới" là FAB, và việc neo nó vào một thanh ở dưới cùng giúp người dùng luôn có sẵn tùy chọn tạo mới.
- Ứng dụng chỉnh sửa ảnh/video đơn giản: Các nút hành động như "Lưu", "Chia sẻ", "Hoàn tác" có thể được đặt trên một
BottomAppBarđể dễ dàng truy cập trong quá trình chỉnh sửa.
Nhớ nhé, BottomAppBar không chỉ là một mảnh UI, nó là một công cụ mạnh mẽ để định hình trải nghiệm người dùng, giúp họ tập trung vào những hành động quan trọng nhất. Hãy sử dụng nó một cách thông minh và sáng tạo để ứng dụng của bạn không chỉ đẹp mà còn "dễ sống" nữa!
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é!