
1. Triết lý “Everything is a Widget” (Cơ chế Composition)
Trong Flutter, Widget không chỉ là một Component UI (như Button hay Label), nó là một Configuration (Cấu hình).
- Logic lắp ghép (Composition over Inheritance): Thay vì tạo ra một Class phức tạp kế thừa hàng chục thuộc tính, Flutter dùng các Widget nhỏ thực hiện duy nhất một nhiệm vụ (Single Responsibility).
- Muốn căn giữa? Dùng Widget
Center. - Muốn cách lề? Dùng Widget
Padding. - Muốn bắt sự kiện? Dùng Widget
GestureDetector.
- Muốn căn giữa? Dùng Widget
- Hệ quả: Một màn hình là một cây Widget (Widget Tree). Tại đỉnh cao nhất là
MaterialApp(hoặcCupertinoApp), và các nhánh con là sự lồng ghép vô tận của các Widget khác. Điều này giúp độ phức tạp của UI được giải quyết bằng cách chia nhỏ module.
2. Quản lý trạng thái (State Management & Reactive UI)
Dân kỹ thuật nhìn UI của Flutter qua công thức toán học:UI = f(state)
- StatelessWidget (Immutable): Là các Widget có hằng số. Khi đã build, thuộc tính không thay đổi. Phù hợp cho các thành phần tĩnh để tối ưu bộ nhớ.
- StatefulWidget (Mutable): Cho phép UI thay đổi theo thời gian.Cơ chế Re-render: Khi trạng thái ($state$) thay đổi, hàm
setState()được gọi. Flutter sẽ chạy lại hàmbuild()để tạo ra một Widget Tree mới. - Thuật toán Diffing: Flutter không hủy toàn bộ màn hình để vẽ lại (vì quá tốn kém). Nó so sánh cây cũ và cây mới, xác định chính xác Node nào thay đổi và chỉ cập nhật phần đó trên Layer Rendering. Hiệu năng đạt mức 60fps – 120fps.
3. GestureDetector (Cơ chế hướng sự kiện)
Nếu Widget là “xác” thì GestureDetector là “hệ thần kinh”.
- Invisible Wrapper: Đây là một Widget không có hình thái hiển thị. Nó bao bọc lấy một Widget khác để lắng nghe các sự kiện thô từ phần cứng (màn hình cảm ứng).
- Event Mapping: Nó chuyển đổi các tín hiệu chạm (Touch events) thành các hành động có ý nghĩa:
onTap: Nhấn nhanh.onLongPress: Nhấn giữ.onPanUpdate: Kéo rê (Drag).
- Tính tùy biến: Bạn có thể biến bất cứ thứ gì (một dòng chữ, một tấm ảnh) thành một nút bấm bằng cách bọc nó trong
GestureDetector.
4. Layered Architecture (Phân tầng hệ thống)
Flutter không sử dụng các UI Component có sẵn của hệ điều hành (Native Controls). Nó tự vẽ mọi thứ. Kiến trúc này được chia làm 3 tầng chính:
| Tầng (Layer) | Thành phần chính | Vai trò kỹ thuật |
| Framework (Dart) | Widgets, Material, Cupertino, Animation. | Nơi lập trình viên thao tác. Cung cấp các khối xây dựng bậc cao. |
| Engine (C++) | Skia (Graphics Engine), Dart VM, Text. | Tầng thấp lo việc tính toán tọa độ pixel, nạp font và quản lý bộ nhớ. |
| Embedder (Platform) | Shell (Android/iOS/Windows). | Tầng giao tiếp với phần cứng, quản lý vòng đời ứng dụng và luồng sự kiện. |
5. Phân tích luồng dữ liệu (Data Flow) trong một App cơ bản
Từ thông tin bạn cung cấp, ta suy ra luồng vận hành của một ứng dụng như sau:
- Khởi tạo:
main()gọirunApp(MyApp). - Dựng khung:
MaterialAppthiết lập các thông số về Theme và Navigation. - Dựng xương:
Scaffoldcung cấp các slot (Body, AppBar, FloatingActionButton, Drawer) để lập trình viên “đổ” dữ liệu vào đúng vị trí. - Bố cục:
Centertính toán tọa độ dựa trên kích thước của Parent (là Scaffold) và Child (là Text). - Hiển thị:
Textnhận chuỗi String và gửi xuống Engine để vẽ từng nét chữ lên màn hình thông qua Skia.
Kết luận: Flutter giống như việc lắp ghép các khối
Lego. Mỗi khối là một Widget, và sức mạnh nằm ở chỗ các khối này có thể lồng vào nhau không giới hạn để tạo nên những hệ thống phức tạp nhưng vẫn đảm bảo tính module hóa cực cao.
Widget
1. Bản chất của Widget: Cơ chế “Build”
Mọi Widget trong Flutter đều hoạt động dựa trên một nguyên lý: Đệ quy khởi tạo.
- Hàm
build(BuildContext context): Đây là trái tim của một Widget. Nó không “vẽ” lên màn hình mà “trả về” một cấu trúc Widget khác. - Luồng thực thi: *
MyHomePagegọiScaffold.ScaffoldgọiAppBarvàCenter.CentergọiImagehoặcText.
- Ý nghĩa kỹ thuật: Điều này tạo ra một Cây Widget (Widget Tree).
BuildContextchính là “tọa độ” của Widget đó trong cây để hệ thống biết nó đang nằm ở đâu và nhận dữ liệu từ cha nào.
2. Phân loại Widget theo công năng
Flutter chia Widget thành 4 nhóm chiến lược để quản lý giao diện và trải nghiệm:
A. Platform Specific (Widget đặc thù nền tảng)
Flutter không dùng UI của hệ điều hành nhưng nó “giả lập” hoàn hảo ngôn ngữ thiết kế của họ:
- Material Design (Android): Các Widget như
Scaffold,FloatingActionButton,AppBar. Mang phong cách đổ bóng, hiện đại của Google. - Cupertino (iOS): Các Widget như
CupertinoButton,CupertinoNavigationBar. Mang phong cách mờ ảo (blur) và tối giản của Apple.
B. Layout Widgets (Widget bố cục)
Đây là các Widget đóng vai trò “định vị” cho các Widget con:
- Container: Widget đa năng (như thẻ
<div>trong Web), dùng để tạo khung, đổ màu, bo góc, tạo bóng. - Row/Column: Sắp xếp theo trục ngang/dọc (tương tự Flexbox).
- Stack: Chồng các Widget lên nhau theo chiều sâu (Z-axis).
C. State Maintenance (Widget quản lý trạng thái)
- StatelessWidget: Dùng cho dữ liệu tĩnh. Một khi đã dựng xong là “đóng băng”, không thay đổi trừ khi Widget cha dựng lại nó.
- StatefulWidget: Có khả năng tự làm mới chính mình khi dữ liệu bên trong (
State) thay đổi.
D. Basic/Independent Widgets (Widget cơ bản)
Các đơn vị hiển thị nội dung nguyên tử:
- Text: Hiển thị chuỗi. Có
Text.richđể định dạng kiểu “mỗi chữ một màu” (dùngTextSpan). - Image: Có 4 nguồn nạp dữ liệu chính:
asset(trong app),file(trong máy),network(từ internet),memory(từ mảng byte). - Icon: Sử dụng glyph từ font chữ (như
Icons.email), giúp icon sắc nét ở mọi độ phân giải mà không tốn dung lượng như ảnh.
3. Điểm nhấn kỹ thuật cần lưu ý
Thuộc tính Key
Trong constructor: MyHomePage({Key key, ...}).
- Vai trò: Giúp Flutter định danh chính xác một Widget khi nó di chuyển trong cây Widget. Cực kỳ quan trọng khi bạn có một danh sách các phần tử giống hệt nhau và muốn thay đổi thứ tự hoặc xóa chúng mà không làm mất trạng thái (state).
Quản lý Asset (Ảnh/Font)
Để dùng ảnh trong Flutter, bạn phải khai báo trong file cấu hình hệ thống: pubspec.yaml.
- Logic: Đăng ký đường dẫn > Flutter đóng gói vào file cài đặt (APK/IPA) > Dùng
Image.assetđể gọi.
4. Tóm tắt mô hình vận hành
- Dữ liệu đầu vào: Thông qua Constructor (ví dụ:
this.title). - Xử lý: Hàm
buildtính toán logic hiển thị. - Đầu ra: Trả về một Widget con phức hợp.
- Hiển thị: Engine Render quét qua cây Widget và vẽ các pixel tương ứng.
Nhận xét: Bài giảng này cung cấp cái nhìn tổng quan từ cấu trúc code (Class/Override) đến cách tổ chức thư viện Widget. Nếu bạn nắm chắc nhóm Layout và Basic, bạn đã có thể xây dựng 80% giao diện ứng dụng. 20% còn lại nằm ở việc tối ưu hóa hiệu năng với StatefulWidget.
Leave a Reply