1. Widget trong Flutter là gì?

Widget là thành phần cơ bản nhất được sử dụng để xây dựng giao diện trong Flutter. Mỗi thành phần trên màn hình như văn bản, hình ảnh, nút bấm, danh sách, khoảng cách hoặc toàn bộ một màn hình đều có thể được biểu diễn bằng Widget.

Thay vì xây dựng giao diện bằng cách điều khiển từng thành phần riêng lẻ, Flutter sử dụng các Widget để mô tả giao diện mà ứng dụng cần hiển thị.

Có thể hiểu đơn giản:

Widget → kết hợp nhiều Widget → tạo thành giao diện → tạo thành màn hình ứng dụng

Ví dụ một màn hình có thể được tạo từ Scaffold, bên trong có AppBar, Column, Text, Image, Button và nhiều Widget khác.

  1. Đặc điểm của Widget

Widget trong Flutter có một số đặc điểm quan trọng:

  • Là thành phần nền tảng để xây dựng UI.
  • Có thể chứa các Widget khác.
  • Có thể được kết hợp và lồng nhau.
  • Có thể tái sử dụng ở nhiều vị trí.
  • Mỗi Widget mô tả một phần giao diện hoặc cách bố trí giao diện.
  • Widget được tổ chức thành một cấu trúc phân cấp gọi là Widget Tree.

Một giao diện Flutter thường không phải là một Widget duy nhất mà là nhiều Widget kết hợp với nhau.

  1. Widget Tree là gì?

Widget Tree là cấu trúc cây thể hiện mối quan hệ giữa các Widget trong giao diện Flutter.

Một Widget có thể là Widget cha và chứa nhiều Widget con. Các Widget con lại có thể tiếp tục chứa những Widget khác.

Ví dụ:

Scaffold
├── AppBar
└── Column
    ├── Text
    ├── Image
    └── ElevatedButton

Trong ví dụ trên, Scaffold là Widget cha lớn, bên trong có AppBar và phần nội dung Column. Column tiếp tục chứa Text, Image và ElevatedButton.

Việc tổ chức giao diện thành Widget Tree giúp Flutter xác định cấu trúc và cách các thành phần giao diện được bố trí với nhau.

  1. Widget có thể lồng nhau

Một đặc điểm quan trọng của Flutter là Widget có thể chứa Widget khác.

Ví dụ:

Scaffold(
  body: Column(
    children: [
      const Text('Sản phẩm'),
      ElevatedButton(
        onPressed: () {},
        child: const Text('Mua hàng'),
      ),
    ],
  ),
)

Trong đoạn code trên, Scaffold chứa Column, Column chứa Text và ElevatedButton, còn ElevatedButton lại chứa một Text.

Đây chính là cách Flutter xây dựng giao diện bằng cách kết hợp các Widget nhỏ thành Widget lớn hơn.

  1. StatelessWidget và StatefulWidget

Trong Flutter, Widget thường được chia thành hai loại quan trọng là: StatelessWidget và StatefulWidget.

StatelessWidget

StatelessWidget là Widget không có State riêng cần thay đổi trong quá trình hoạt động. Widget nhận dữ liệu đầu vào và sử dụng dữ liệu đó để xây dựng giao diện.

Ví dụ:

class ProductTitle extends StatelessWidget {
  const ProductTitle({super.key});

  @override
  Widget build(BuildContext context) {
    return const Text('Sữa Abbott');
  }
}

StatelessWidget thường phù hợp với những thành phần giao diện đơn giản hoặc không cần tự quản lý trạng thái thay đổi.

StatefulWidget

StatefulWidget là Widget có State có thể thay đổi trong quá trình ứng dụng chạy. Ví dụ những thành phần như ô nhập liệu, bộ đếm hoặc giao diện có trạng thái thay đổi có thể cần StatefulWidget.

Phần StatefulWidget vs StatelessWidget là một keyword riêng Anh Huy giao, vì vậy ở phần Fundamentals chỉ cần nắm khái niệm cơ bản này, không cần đi sâu vào vòng đời của State.

  1. Hàm build()

build() là phương thức quan trọng trong Widget. Nó có nhiệm vụ mô tả giao diện mà Widget cần hiển thị.

Ví dụ:

@override
Widget build(BuildContext context) {
  return const Text('Hello Flutter');
}

Giá trị trả về của build() là một Widget.

Do đó có thể hiểu:

build() → trả về Widget → Widget tạo thành giao diện

Trong Flutter, build() có thể được gọi lại khi giao diện cần được xây dựng lại. Vì vậy, phương thức này chủ yếu nên tập trung vào việc mô tả UI.

  1. Một số Widget cơ bản cần biết

Khi học Flutter Widget Fundamentals, cần làm quen với một số Widget thường xuyên xuất hiện trong project:

Text: Dùng để hiển thị văn bản.

const Text('Xin chào Flutter')

Image: Dùng để hiển thị hình ảnh.

Image.asset('images/product.png')

Container: Dùng làm vùng chứa và cho phép thiết lập các thuộc tính như kích thước, màu nền, khoảng cách và đường viền.

Row: Dùng để sắp xếp các Widget theo chiều ngang.

Row → Widget 1 | Widget 2 | Widget 3

Column: Dùng để sắp xếp các Widget theo chiều dọc.

Column
  ↓
Widget 1
  ↓
Widget 2
  ↓
Widget 3

Stack: Dùng để đặt các Widget chồng lên nhau.

Expanded: Dùng để cho một Widget con mở rộng để sử dụng phần không gian còn lại trong Row, Column hoặc Flex.

ListView: Dùng để hiển thị danh sách có thể cuộn.

Scaffold: Cung cấp cấu trúc cơ bản cho một màn hình Flutter, thường kết hợp với AppBar, body, FloatingActionButton, Drawer…

ElevatedButton: Dùng để tạo nút bấm.

TextField: Dùng để cho người dùng nhập dữ liệu.

  1. Widget dùng để xây dựng giao diện như thế nào?

Một giao diện thực tế thường được xây dựng từ nhiều cấp Widget.

Ví dụ màn hình sản phẩm:

Scaffold
└── Column
    ├── Text
    ├── Image
    ├── Text
    └── ElevatedButton

Mỗi Widget đảm nhiệm một phần nhỏ của giao diện. Khi kết hợp chúng lại, Flutter có thể tạo thành một màn hình hoàn chỉnh.

Đây là tư duy quan trọng khi làm Flutter: không xây dựng cả màn hình thành một khối lớn mà chia giao diện thành các Widget nhỏ và kết hợp chúng lại.

  1. Tái sử dụng Widget

Widget có thể được tạo thành các thành phần riêng để sử dụng nhiều lần.

Ví dụ trong ứng dụng bán hàng có thể tạo:

  • ProductItem
  • ProductCard
  • CategoryItem
  • SearchBox
  • AppButton

Sau đó sử dụng lại những Widget này ở nhiều màn hình khác nhau. Việc tái sử dụng Widget giúp:

  • Giảm code trùng lặp.
  • Code dễ đọc hơn.
  • Dễ chỉnh sửa giao diện.
  • Dễ bảo trì project.

Đây là một trong những lợi ích quan trọng của cách xây dựng giao diện bằng Widget.

  1. Flutter xây dựng UI bằng Widget

Flutter sử dụng cách tiếp cận declarative UI, nghĩa là lập trình viên chủ yếu mô tả giao diện cần hiển thị dựa trên dữ liệu và trạng thái hiện tại.

Thay vì phải tự điều khiển từng bước để thay đổi giao diện, lập trình viên xây dựng các Widget mô tả giao diện mong muốn, sau đó Flutter đảm nhiệm quá trình cập nhật giao diện.

Có thể hiểu ngắn gọn:

Dữ liệu/State → Widget mô tả UI → Flutter xây dựng giao diện

Đây là tư duy nền tảng khi làm việc với Flutter.

  1. Những ý chính cần nhớ
- Widget là thành phần cơ bản để xây dựng UI trong Flutter.
- Một giao diện được tạo thành từ nhiều Widget kết hợp với nhau.
- Widget Tree thể hiện cấu trúc cha – con của các Widget.
- Widget có thể lồng nhau và tái sử dụng.
- StatelessWidget và StatefulWidget là hai loại Widget quan trọng.
- build() dùng để mô tả giao diện của Widget.
- Cần nắm các Widget cơ bản như Text, Image, Container, Row, Column, Stack, Expanded, ListView, Scaffold, Button, TextField.
- Flutter sử dụng cách tiếp cận declarative UI để xây dựng giao diện.
- Trong project thực tế nên chia giao diện thành các Widget nhỏ để dễ quản lý và tái sử dụng.
  1. Kết luận

Flutter Widget Fundamentals là kiến thức nền tảng để bắt đầu làm giao diện bằng Flutter. Cốt lõi của phần này là hiểu Widget là gì, Widget Tree hoạt động như thế nào, cách các Widget lồng nhau và những Widget cơ bản dùng để xây dựng giao diện.

Sau khi nắm được phần Fundamentals, có thể tiếp tục học sâu hơn về StatelessWidget vs StatefulWidget, sau đó đến Flutter Layout & Responsive UI và các keyword tiếp theo.

 

Bài viết khác

JSON & HTTP Status Codes

1. JSON là gì? JSON là một định dạng dữ liệu được sử dụng rất phổ biến trong lập trình, đặc biệt là khi Client và Server cần trao đổi dữ liệu với nhau. JSON có cách tổ chức dữ liệu khá đơn giản và dễ đọc. Dữ liệu thường được biểu diễn theo dạng […]

Tìm hiểu về Isolate & Concurrency

  Isolate là gì? Trong Dart, Isolate là một vùng thực thi độc lập, có bộ nhớ riêng và Event Loop riêng. Mỗi Isolate có thể thực hiện công việc mà không trực tiếp chia sẻ bộ nhớ với Isolate khác. Có thể hiểu đơn giản: Isolate là cách Dart thực hiện các tác vụ […]

Lập trình bất đồng bộ với Future, async, await.

  Lập trình bất đồng bộ là gì? Lập trình bất đồng bộ (Asynchronous Programming) là cách tổ chức chương trình cho phép một tác vụ mất thời gian được thực hiện mà không cần chặn toàn bộ chương trình trong thời gian chờ. Trong ứng dụng thực tế, có nhiều công việc cần thời […]

Tìm hiểu về Null Safety

  Null Safety là gì? Null Safety là một cơ chế an toàn kiểu dữ liệu được Dart sử dụng để hạn chế các lỗi liên quan đến giá trị null trong chương trình. Null Safety được đưa vào Dart nhằm giúp lập trình viên xác định rõ một biến có thể chứa null hay […]

TÌM HIỂU VỀ DART OO

  Dart OOP là gì? Dart OOP là lập trình hướng đối tượng (Object-Oriented Programming) trong ngôn ngữ Dart. Đây là phương pháp lập trình tổ chức chương trình xoay quanh đối tượng (Object) thay vì chỉ sử dụng các biến và hàm riêng lẻ. Trong OOP, một đối tượng thường có dữ liệu và […]

Tìm hiểu về ngôn ngữ lập trình Dart

  Dart là gì? Dart là một ngôn ngữ lập trình mã nguồn mở được phát triển bởi Google, được sử dụng để xây dựng các ứng dụng có thể chạy trên nhiều nền tảng khác nhau. Hiện nay, Dart được biết đến nhiều nhất vì đây là ngôn ngữ lập trình chính được sử […]

Leave a Reply

Your email address will not be published. Required fields are marked *