📚 Stack Widget
1. Giới thiệu
Phần tiêu đề “1. Giới thiệu”Stack cho phép xếp chồng widgets lên nhau:
Stack( children: [ Container(width: 200, height: 200, color: Colors.red), // Dưới cùng Container(width: 150, height: 150, color: Colors.green), // Giữa Container(width: 100, height: 100, color: Colors.blue), // Trên cùng ],)Nguyên lý xếp chồng (Layering)
Phần tiêu đề “Nguyên lý xếp chồng (Layering)”Stack vẽ các children theo thứ tự: First-in, Bottom-out (Cái nào vào trước nằm dưới cùng).
STACK VISUALIZATION
┌──────────────┐ │ Top (3) │ ← Last Child (Blue) ┌─┴────────────┐ │ │ Middle (2) │ │ ← Middle Child (Green) ┌─┴────────────┐ │ │ │ Bottom (1) │ │ │ ← First Child (Red) └──────────────┘─┴─┘
(3) che khuất (2) (2) che khuất (1)2. Alignment
Phần tiêu đề “2. Alignment”Stack( alignment: Alignment.center, // Căn tất cả children vào giữa children: [ Container(width: 200, height: 200, color: Colors.grey), Container(width: 100, height: 100, color: Colors.blue), ],)3. Positioned Widget
Phần tiêu đề “3. Positioned Widget”Định vị chính xác child trong Stack:
Stack( children: [ Container(width: 200, height: 200, color: Colors.grey), Positioned( top: 10, left: 10, child: Container(width: 50, height: 50, color: Colors.red), ), Positioned( bottom: 10, right: 10, child: Container(width: 50, height: 50, color: Colors.blue), ), ],)Positioned properties
Phần tiêu đề “Positioned properties”| Property | Mô tả |
|---|---|
top |
Khoảng cách từ top |
bottom |
Khoảng cách từ bottom |
left |
Khoảng cách từ left |
right |
Khoảng cách từ right |
width |
Chiều rộng cố định |
height |
Chiều cao cố định |
4. Positioned.fill
Phần tiêu đề “4. Positioned.fill”Kéo dãn child full Stack:
Stack( children: [ Positioned.fill( child: Container(color: Colors.grey), ), Center( child: Text('Centered'), ), ],)5. fit Property
Phần tiêu đề “5. fit Property”Stack( fit: StackFit.expand, // Kéo dãn children không có Positioned children: [...],)| Giá trị | Mô tả |
|---|---|
loose |
Children có thể nhỏ hơn Stack (mặc định) |
expand |
Kéo dãn non-positioned children full Stack |
passthrough |
Giữ constraints từ parent |
6. clipBehavior
Phần tiêu đề “6. clipBehavior”Stack( clipBehavior: Clip.none, // Cho phép children tràn ra ngoài children: [ Container(width: 100, height: 100, color: Colors.grey), Positioned( top: -20, left: -20, child: Container(width: 50, height: 50, color: Colors.red), ), ],)7. Ví dụ thực tế
Phần tiêu đề “7. Ví dụ thực tế”Badge trên Icon
Phần tiêu đề “Badge trên Icon”Stack( clipBehavior: Clip.none, children: [ Icon(Icons.notifications, size: 30), Positioned( top: -5, right: -5, child: Container( padding: EdgeInsets.all(4), decoration: BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), child: Text( '3', style: TextStyle(color: Colors.white, fontSize: 10), ), ), ), ],)Image với Overlay
Phần tiêu đề “Image với Overlay”Stack( children: [ Image.network( 'https://picsum.photos/200', width: 200, height: 200, fit: BoxFit.cover, ), Positioned( bottom: 0, left: 0, right: 0, child: Container( padding: EdgeInsets.all(8), color: Colors.black54, child: Text( 'Image Title', style: TextStyle(color: Colors.white), ), ), ), ],)Floating Action Button Style
Phần tiêu đề “Floating Action Button Style”Stack( children: [ // Main content ListView.builder( itemCount: 20, itemBuilder: (context, index) => ListTile(title: Text('Item $index')), ), // FAB positioned Positioned( bottom: 16, right: 16, child: FloatingActionButton( onPressed: () {}, child: Icon(Icons.add), ), ), ],)Profile Avatar với Status
Phần tiêu đề “Profile Avatar với Status”Stack( children: [ CircleAvatar( radius: 40, backgroundImage: NetworkImage('https://...'), ), Positioned( bottom: 0, right: 0, child: Container( width: 20, height: 20, decoration: BoxDecoration( color: Colors.green, shape: BoxShape.circle, border: Border.all(color: Colors.white, width: 2), ), ), ), ],)8. IndexedStack
Phần tiêu đề “8. IndexedStack”Chỉ hiển thị một child tại một thời điểm:
IndexedStack( index: currentIndex, // 0, 1, hoặc 2 children: [ Container(color: Colors.red), Container(color: Colors.green), Container(color: Colors.blue), ],)Hữu ích cho tab switching mà muốn giữ state.
📝 Tóm tắt
Phần tiêu đề “📝 Tóm tắt”| Widget/Property | Mục đích |
|---|---|
Stack |
Xếp chồng widgets |
Positioned |
Định vị chính xác trong Stack |
alignment |
Căn chỉnh mặc định cho children |
fit |
Cách sizing children |
clipBehavior |
Cho phép/không cho tràn |
IndexedStack |
Hiển thị một child theo index |