💡 Giới thiệu Widget
1. Widget là gì?
Phần tiêu đề “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ị textContainer() // Widget chứa nội dungRow() // Widget sắp xếp theo hàngElevatedButton() // Widget button“Everything is a Widget” là triết lý cốt lõi của Flutter.
2. Widget Tree
Phần tiêu đề “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
Phần tiêu đề “3. Phân loại Widgets”StatelessWidget
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “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
Phần tiêu đề “child vs children”// child - một widget conCenter( child: Text('Single child'),)
// children - nhiều widget conColumn( children: [ Text('Child 1'), Text('Child 2'), Text('Child 3'), ],)6. Widget Composition
Phần tiêu đề “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ẵnclass 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ụngProfileCard(name: 'John', avatarUrl: 'https://...')7. BuildContext
Phần tiêu đề “7. BuildContext”BuildContext chứa thông tin về vị trí widget trong tree:
@overrideWidget 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
Phần tiêu đề “8. const Widgets”Sử dụng const để optimize performance:
// Good - widget được tạo một lầnconst Text('Hello')
// Widget không đổi nên dùng constconst Padding( padding: EdgeInsets.all(8), child: Text('Static content'),)📝 Tóm tắt
Phần tiêu đề “📝 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 |