
Chào các chiến hữu lập trình! Hôm nay, chúng ta sẽ lặn sâu vào một viên ngọc ẩn của Flutter, thứ mà nhiều bạn thường bỏ qua nhưng lại cực kỳ quyền năng trong việc xây dựng giao diện người dùng linh hoạt, đó là FractionallySizedBox.
Cứ hình dung thế này: trong thế giới lập trình UI, đôi khi bạn cần một widget không phải to đúng 'X pixels' hay 'Y pixels' cố định. Mà bạn lại muốn nó to bằng 'một nửa không gian cha nó' hay 'một phần ba chiều cao của cái màn hình ấy'. Nó giống như bạn đi may quần áo vậy, thay vì nói 'cái ống quần này rộng 20cm', bạn nói 'nó rộng bằng 30% vòng đùi của tôi'. Đấy, cái '30%' ấy chính là linh hồn của FractionallySizedBox!
Vậy, FractionallySizedBox làm gì? Đơn giản là nó cho phép bạn định nghĩa kích thước của widget con (child) DỰA TRÊN tỷ lệ phần trăm của kích thước widget cha (parent) có sẵn. Nó không tự tạo ra không gian, mà nó 'thò tay' vào cái không gian mà thằng cha nó đã cấp cho nó, rồi 'cắt' ra một phần theo đúng tỷ lệ bạn muốn cho thằng con.
Nó có hai thuộc tính chính, như hai cái kéo sắc bén để bạn cắt vải vậy:
widthFactor: Cái này quyết định chiều rộng của widget con sẽ bằng bao nhiêu phần của chiều rộng widget cha. Giá trị từ0.0(rộng 0%) đến1.0(rộng 100%).heightFactor: Tương tự, nhưng là cho chiều cao. Từ0.0đến1.0.
Nếu bạn chỉ định một trong hai (hoặc cả hai), thằng con sẽ được co giãn theo tỷ lệ đó. Nếu bạn không chỉ định, nó sẽ mặc định là null, tức là không ảnh hưởng đến kích thước đó, để thằng con tự quyết hoặc để thằng cha quyết định.

Nói nhiều không bằng làm một phát ăn ngay! Hãy xem ví dụ này để thấy nó hoạt động như thế nào trong thực tế:
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: 'FractionallySizedBox 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('FractionallySizedBox của Creyt'),
),
body: Center(
child: Container(
color: Colors.grey[300], // Màu nền của widget cha để dễ hình dung
width: 300, // Chiều rộng cố định của cha
height: 300, // Chiều cao cố định của cha
child: FractionallySizedBox(
widthFactor: 0.75, // Con chiếm 75% chiều rộng của cha
heightFactor: 0.5, // Con chiếm 50% chiều cao của cha
child: Container(
color: Colors.deepPurple, // Màu của widget con
child: const Center(
child: Text(
'Tôi là con, tôi chiếm 75% rộng và 50% cao của cha!',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.white, fontSize: 16),
),
),
),
),
),
),
);
}
}
Trong ví dụ trên, cái Container màu tím sẽ chiếm 75% chiều rộng và 50% chiều cao của cái Container màu xám. Mặc dù thằng cha màu xám có kích thước cố định, nhưng thằng con màu tím lại 'nhìn' vào kích thước đó và tự điều chỉnh theo tỷ lệ. Ngon lành cành đào!
Rồi, giờ là vài chiêu thức 'phòng the' để các bạn dùng FractionallySizedBox cho nó pro:
- Hiểu rõ 'Cha' của bạn:
FractionallySizedBoxcần một widget cha có ràng buộc kích thước (constraints) rõ ràng. Nếu cha nó là một cáiColumnhayRow(mà không cóExpandedhayFlexibleđi kèm), hoặc mộtListViewkhông giới hạn kích thước, thìFractionallySizedBoxsẽ không biết '100%' là bao nhiêu mà tính toán. Nó sẽ 'bối rối' và có thể ném lỗi hoặc không hoạt động như ý. Luôn đảm bảo cha nó cung cấp một không gian hữu hạn để nó 'cắt'. - Kết hợp với
AlignhoặcCenter:FractionallySizedBoxchỉ lo chuyện kích thước, nó không quan tâm đến vị trí của thằng con. Nếu bạn muốn thằng con nằm giữa cái không gian màFractionallySizedBoxđã 'cắt' ra, hãy bọc nó trongCenterhoặc dùngalignmentcủaFractionallySizedBox(mặc định làAlignment.center). - Dùng cho Responsive Design: Đây chính là 'sân nhà' của nó! Khi bạn muốn một thành phần UI tự động co giãn theo kích thước màn hình (mà kích thước màn hình là cha của mọi thứ),
FractionallySizedBoxlà một lựa chọn tuyệt vời. Ví dụ, một banner chiếm 80% chiều rộng màn hình, bất kể màn hình to hay nhỏ. - Không phải lúc nào cũng là giải pháp: Đừng lạm dụng nó. Đôi khi
Expanded,Flexible, hoặc đơn giản làSizedBoxvới kích thước cố định lại là lựa chọn tốt hơn, tùy vào ngữ cảnh.FractionallySizedBoxlà cho các trường hợp bạn cần sizing theo TỶ LỆ.
Giờ thì, ứng dụng thực tế nó ở đâu? Không phải chỉ trên sách vở đâu nha:
- Bảng điều khiển (Dashboards): Tưởng tượng một dashboard với các card thông tin. Bạn muốn mỗi card chiếm 30% chiều rộng của hàng, hoặc một biểu đồ chiếm 60% chiều cao của khu vực hiển thị.
FractionallySizedBoxlà 'tay chơi' chính ở đây. - Thanh tiến độ (Progress Bars): Một thanh tiến độ thường có phần 'đã hoàn thành' chiếm một tỷ lệ nhất định của tổng chiều dài thanh. Dễ dàng dùng
FractionallySizedBoxđể điều khiển chiều rộng của phần 'đã hoàn thành' theo mộtvaluetừ 0.0 đến 1.0. - Layout lưới ảnh (Image Grids): Bạn muốn mỗi ảnh trong một hàng chiếm 1/3 chiều rộng màn hình (trừ padding)? Dùng
FractionallySizedBoxkết hợp vớiGridViewhoặcRowlà ra ngay. - Các thành phần UI đáp ứng (Responsive UI Components): Bất cứ khi nào bạn có một component mà kích thước của nó cần thay đổi tỷ lệ thuận với kích thước của parent (mà parent có thể là toàn bộ màn hình),
FractionallySizedBoxlà một công cụ cực kỳ hữu ích. Ví dụ, một nút bấm chiếm 70% chiều rộng của một card.
Tóm lại, FractionallySizedBox là một công cụ mạnh mẽ trong bộ đồ nghề của lập trình viên Flutter, giúp bạn tạo ra những giao diện linh hoạt, thích ứng tốt với mọi kích thước màn hình. Nắm vững nó, bạn sẽ có thêm một 'vũ khí' lợi hại để chinh phục thế giới UI/UX đấy!
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é!