Flexible: nó là gì, nguyên lý hoạt động và cấu hình trong phát triển di động

Tác giả: IT Sectr Đã đăng: 2026-07-03 Thời gian đọc: 6 phút

Flexible là một widget Flutter điều khiển cách phần tử con chiếm không gian có sẵn trong bộ chứa Flex. Không giống như Expanded, Flexible không buộc phần tử con phải lấp đầy toàn bộ khu vực được cấp phát — widget con có thể nhỏ hơn và không gian còn lại vẫn trống. Theo tài liệu chính thức của Flutter (2026), Flexible cần thiết trong các tình huống yêu cầu phân phối không gian linh hoạt mà không kéo giãn cưỡng bức: các nút có chiều rộng tối thiểu, khối văn bản có kích thước tự nhiên và các phần tử có intrinsic constraints.

Những Điểm Chính

  • Flexible là một widget bố cục để phân phối không gian linh hoạt trong Row, Column hoặc Flex
  • FlexFit.loose cho phép phần tử con nhỏ hơn không gian được cấp, FlexFit.tight buộc phải lấp đầy
  • Flexible với loose phù hợp với các widget có kích thước được xác định bởi nội dung
  • Khác biệt với Expanded: Expanded không có tham số fit và luôn hoạt động như tight
  • Hệ số flex hoạt động giống nhau cho cả Flexible và Expanded — phần không gian trống

Flexible là gì

Flexible là một widget bao bọc cung cấp không gian linh hoạt cho phần tử con trong bộ chứa Flex. Flexible, giống như Expanded, tham gia vào việc phân phối không gian trống, nhưng với một điểm khác biệt chính: phần tử con của Flexible có thể chiếm ít không gian hơn mức được cấp nếu kích thước của nó nhỏ hơn không gian có sẵn.

Flexible sử dụng thuật toán Flex của Flutter để tính toán không gian có sẵn. Đầu tiên, framework truy vấn tất cả các phần tử con không linh hoạt (widget không có Flexible/Expanded) và tính toán kích thước nội tại của chúng. Không gian còn lại được chia cho các phần tử con linh hoạt theo tỷ lệ hệ số flex của chúng. Sau khi cấp phát không gian, Flexible kiểm tra fit — nếu là loose, phần tử con nhận được ràng buộc là “không lớn hơn mức được cấp”, cho phép nó giữ kích thước nhỏ.

Một đặc điểm của Flexible: nếu widget con có kích thước tối thiểu riêng (ví dụ: Text với chuỗi dài), Flexible cấp phát không gian được yêu cầu mà không kéo giãn cưỡng bức. Điều này làm cho Flexible không thể thiếu cho các phần tử có kích thước được xác định bởi nội dung thay vì bộ chứa.

Tóm lại: hãy sử dụng Flexible khi bạn cần dành không gian cho một phần tử nhưng không buộc nó phải kéo giãn. Điều này bảo tồn kích thước tự nhiên của nội dung trong khi duy trì phân phối bố cục linh hoạt.

FlexFit.tight vs FlexFit.loose

FlexFit là một kiểu liệt kê gồm hai giá trị: tight và loose. Việc chọn fit quyết định liệu widget con có bị kéo giãn cưỡng bức đến kích thước của không gian được cấp hay không.

FlexFit.tight: phần tử con nhận được tight constraints — kích thước tối thiểu và tối đa bằng với không gian được cấp. Phần tử con phải chiếm chính xác không gian mà thuật toán Flex đã cấp. Nếu phần tử con nhỏ hơn — nó bị kéo giãn. Nếu lớn hơn — nó bị co lại. Hành vi này giống hệt với Expanded.

FlexFit.loose: phần tử con nhận được loose constraints — kích thước tối thiểu là 0, tối đa bằng với không gian được cấp. Phần tử con có thể có bất kỳ kích thước nào từ 0 đến tối đa. Nếu phần tử con nhỏ (ví dụ: Text với chuỗi ngắn), nó chiếm chiều rộng tự nhiên và không gian còn lại vẫn trống.

Tóm lại: FlexFit.loose là lựa chọn cho các khối văn bản và phần tử có kích thước tự nhiên. FlexFit.tight dành cho bố cục cột nghiêm ngặt nơi tất cả các phần tử phải có cùng chiều rộng hoặc chiều cao.

Khi nào sử dụng Flexible thay vì Expanded

FlexibleExpanded trông giống nhau nhưng giải quyết các nhiệm vụ khác nhau. Expanded luôn kéo giãn phần tử con để lấp đầy toàn bộ không gian có sẵn. Flexible có thể để lại không gian trống xung quanh phần tử con nếu kích thước nội dung nhỏ hơn phần được cấp.

Kịch bản cho Flexible: bên trong một Row có hai nút. Nút đầu tiên — “Mua” (văn bản ngắn), nút thứ hai — “Thêm vào giỏ hàng” (văn bản dài). Với Expanded, cả hai nút đều bị kéo giãn đến cùng một chiều rộng và văn bản ngắn sẽ có khoảng đệm rất lớn. Với Flexible, mỗi nút chiếm chiều rộng của văn bản và không gian trống vẫn còn giữa chúng hoặc ở các cạnh.

Kịch bản cho Expanded: bên trong một Column có ba thẻ phải chiếm cùng một chiều cao bất kể nội dung. Expanded chia đều chiều cao có sẵn và mỗi thẻ được kéo giãn đến cùng một kích thước. Flexible với loose sẽ không hoạt động ở đây — một thẻ nhỏ sẽ vẫn nhỏ, phá vỡ thiết kế đồng nhất.

Tóm lại: chọn Flexible khi nội dung quyết định kích thước phần tử và không gian trống xung quanh có thể chấp nhận được. Chọn Expanded khi tất cả các phần tử phải có cùng kích thước bất kể nội dung.

Ví dụ mã với Flexible

Ví dụ 1 minh họa cách sử dụng cơ bản của Flexible với FlexFit.loose trong một Row.

dart
Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.amber,
        child: const Text('ngắn'),
      ),
    ),
    Flexible(
      fit: FlexFit.loose,
      child: Container(
        color: Colors.cyan,
        child: const Text('văn bản dài để trình diễn'),
      ),
    ),
  ],
)

Trong ví dụ, cả hai Flexible đều sử dụng loose fit. Container đầu tiên với văn bản ngắn chiếm chiều rộng tự nhiên của nó. Container thứ hai với văn bản dài — chiều rộng riêng của nó. Row cấp cho mỗi container một nửa chiều rộng có sẵn, nhưng loose fit cho phép các container nhỏ hơn và không gian trống vẫn trống giữa chúng.

Ví dụ 2 — so sánh Flexible với Tight và Loose fit trong một Column.

dart
Column(
  children: [
    Flexible(
      fit: FlexFit.tight,
      child: const Card(
        child: ListTile(
          title: Text('Tight — chiều cao toàn phần kéo giãn'),
        ),
      ),
    ),
    const SizedBox(
      height: 8,
    ),
    Flexible(
      fit: FlexFit.loose,
      child: const Card(
        child: ListTile(
          title: Text('Loose — chiều cao tự nhiên'),
        ),
      ),
    ),
  ],
)

Trong Column, Flexible đầu tiên (tight) kéo giãn Card đến một nửa chiều cao có sẵn. Flexible thứ hai (loose) — Card chiếm chiều cao theo nội dung của nó và không gian còn lại vẫn trống. Về mặt trực quan, có thể thấy tight lấp đầy khu vực một cách cưỡng bức, trong khi loose giữ kích thước nhỏ gọn.

Tóm lại: trong mã sản xuất, Flexible với loose được sử dụng cho các trường biểu mẫu, nút và khối văn bản. Flexible với tight tương đương với Expanded và được sử dụng để phân phối đồng đều.

Lỗi thường gặp khi sử dụng Flexible

Lỗi 1: sử dụng Flexible bên ngoài bộ chứa Flex. Giống như Expanded, Flexible ném LayoutException nếu không được đặt bên trong Row, Column hoặc Flex. Giải pháp: luôn kiểm tra chuỗi widget cha.

Lỗi 2: nhầm lẫn giữa Flexible và Expanded. Các nhà phát triển thường sử dụng Expanded khi cần Flexible với loose fit và ngược lại. Kết quả: Expanded kéo giãn một phần tử có văn bản ngắn, tạo ra lề trống lớn. Giải pháp: nếu kích thước phần tử có thể nhỏ hơn mức được cấp — hãy sử dụng Flexible(fit: FlexFit.loose).

Lỗi 3: hệ số flex bằng không. Flexible với flex=0 hoạt động như một widget không linh hoạt, điều này có thể không trực quan. Nhà phát triển mong đợi hành vi linh hoạt, nhưng phần tử chiếm kích thước tối thiểu. Giải pháp: flex phải ≥1 để phân phối không gian chủ động.

Lỗi 4: Flexible bên trong ScrollView mà không có ràng buộc kích thước. Nếu Flexible ở trong Column bên trong SingleChildScrollView, bộ chứa cuộn cung cấp không gian vô hạn và phân phối flex không hoạt động. Giải pháp: hạn chế kích thước bộ chứa cuộn bằng SizedBox hoặc ConstrainedBox.

Tóm lại: Flexible đòi hỏi sự chú ý đến ngữ cảnh cha giống như Expanded. Điểm khác biệt duy nhất là fit — hãy chọn nó một cách có chủ đích dựa trên nhiệm vụ.

Câu Hỏi Thường Gặp

Flexible khác Expanded như thế nào?

Expanded là Flexible với fit=tight cố định. Sự khác biệt là Expanded có sự ràng buộc cứng nhắc để lấp đầy tất cả không gian có sẵn, trong khi Flexible có thể sử dụng loose fit để bảo tồn kích thước tự nhiên của phần tử con.

Nên chọn fit nào cho các nút trong Row?

Đối với các nút có độ dài văn bản khác nhau, hãy sử dụng Flexible(fit: FlexFit.loose). Mỗi nút sẽ chiếm chiều rộng của nội dung và sẽ không có sự chênh lệch giữa chúng. Expanded sẽ làm cho tất cả các nút có cùng chiều rộng.

Làm thế nào để Flexible hoạt động như Expanded?

Đặt fit: FlexFit.tight — Flexible sẽ buộc phần tử con lấp đầy tất cả không gian được cấp. Ở chế độ này, Flexible hoàn toàn giống hệt Expanded về hành vi.

Flexible có thể giảm kích thước của phần tử con không?

, nếu phần tử con lớn hơn không gian được cấp. Flexible truyền các ràng buộc với kích thước tối đa bằng phần của bộ chứa Flex. Nếu phần tử con vượt quá kích thước này, nó sẽ co lại trong phạm vi ràng buộc.

Flexible có hoạt động trực tiếp với bộ chứa Flex không?

, Flexible hoạt động với bất kỳ bộ chứa Flex nào, bao gồm Row, Column và widget cơ bản Flex với hướng tùy ý. Flex cho phép thiết lập các hướng không chuẩn thông qua mainAxisAlignment và crossAxisAlignment.

Tóm tắt

  • Flexible là một widget để phân phối không gian linh hoạt mà không kéo giãn cưỡng bức phần tử con
  • FlexFit.loose bảo tồn kích thước tự nhiên của nội dung, FlexFit.tight lấp đầy khu vực một cách cưỡng bức
  • Expanded là trường hợp đặc biệt của Flexible với fit=tight, sử dụng Flexible khi bạn cần chọn fit
  • Hệ số flex hoạt động giống nhau cho cả Flexible và Expanded — phần không gian trống
  • Loose fit lý tưởng cho các nút, khối văn bản và phần tử có nội dung động
  • Khuyến nghị: sử dụng Flexible với loose cho các thành phần có kích thước được xác định bởi nội dung

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm