Giới thiệu về Widgets trong Flutter
1. Widget là gì?
Trong Flutter, Widget là thành phần cơ bản để xây dựng UI. Mọi thứ bạn thấy trên màn hình đều là widget:
Text('Hello') // Widget hiển thị text
Container() // Widget chứa nội dung
Row() // Widget sắp xếp theo hàng
ElevatedButton() // Widget button“Everything is a Widget” là triết lý cốt lõi của Flutter.
2. Widget Tree
Flutter UI được tổ chức thành cây widget (Widget Tree):
MaterialApp
└── Scaffold
├── AppBar
│ └── Text
└── Body
└── Center
└── Column
├── Text
└── ElevatedButtonCode tương ứng:
MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: Center(
child: Column(
children: [
Text('Hello'),
ElevatedButton(
onPressed: () {},
child: Text('Click'),
),
],
),
),
),
)3. Phân loại Widgets
StatelessWidget
Widget không có state, không thay đổi theo thời gian:
class GreetingCard extends StatelessWidget {
final String name;
const GreetingCard({super.key, required this.name});
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(16),
child: Text('Hello, $name!'),
);
}
}StatefulWidget
Widget có state, có thể thay đổi và rebuild:
class Counter extends StatefulWidget {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: () {
setState(() {
_count++;
});
},
child: Text('Increment'),
),
],
);
}
}4. Widget Categories
| Category | Ví dụ | Mô tả |
|---|---|---|
| Structural | Container, Padding, Center | Layout và positioning |
| Layout | Row, Column, Stack | Sắp xếp children |
| Display | Text, Image, Icon | Hiển thị nội dung |
| Input | TextField, Checkbox | Nhập liệu |
| Interactive | GestureDetector, InkWell | Xử lý touch |
5. Widget Properties
Mỗi widget có các properties để customize:
Container(
width: 200,
height: 100,
color: Colors.blue,
padding: EdgeInsets.all(16),
margin: EdgeInsets.symmetric(vertical: 8),
child: Text('Content'),
)child vs children
// child - một widget con
Center(
child: Text('Single child'),
)
// children - nhiều widget con
Column(
children: [
Text('Child 1'),
Text('Child 2'),
Text('Child 3'),
],
)6. Widget Composition
Flutter khuyến khích composition over inheritance:
// Tạo widget mới bằng cách kết hợp widgets có sẵn
class ProfileCard extends StatelessWidget {
final String name;
final String avatarUrl;
const ProfileCard({
super.key,
required this.name,
required this.avatarUrl,
});
@override
Widget build(BuildContext context) {
return Card(
child: Padding(
padding: EdgeInsets.all(16),
child: Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(avatarUrl),
),
SizedBox(width: 16),
Text(name, style: TextStyle(fontSize: 18)),
],
),
),
);
}
}
// Sử dụng
ProfileCard(name: 'John', avatarUrl: 'https://...')7. BuildContext
BuildContext chứa thông tin về vị trí widget trong tree:
@override
Widget build(BuildContext context) {
// Lấy theme
final theme = Theme.of(context);
// Lấy screen size
final size = MediaQuery.of(context).size;
return Container(
color: theme.primaryColor,
width: size.width * 0.5,
);
}8. const Widgets
Sử dụng const để optimize performance:
// Good - widget được tạo một lần
const Text('Hello')
// Widget không đổi nên dùng const
const Padding(
padding: EdgeInsets.all(8),
child: Text('Static content'),
)📝 Tóm tắt
| Khái niệm | Mô tả |
|---|---|
| Widget | Building block của Flutter UI |
| Widget Tree | Cấu trúc cây của widgets |
| StatelessWidget | Widget không có state |
| StatefulWidget | Widget có state, có thể rebuild |
| child | Một widget con |
| children | Danh sách widget con |
| const | Optimize widget không thay đổi |
Last updated on