Skip to main content

2 posts tagged with "StatelessWidget"

View All Tags

Stateless và Stateful Widgets trong Flutter

· 4 min read

Stateless vs Stateful Widgets

Trong Flutter, có hai loại widget cơ bản: StatelessWidget và StatefulWidget. Việc hiểu rõ sự khác biệt giữa hai loại widget này là rất quan trọng để xây dựng ứng dụng Flutter hiệu quả.

1. StatelessWidget

StatelessWidget là widget không có state (trạng thái). Nó là immutable (không thể thay đổi) sau khi được tạo.

Đặc điểm của StatelessWidget:

  • Không có state
  • Không thể thay đổi sau khi được tạo
  • Phù hợp cho UI tĩnh
  • Hiệu năng tốt hơn vì không cần rebuild

Ví dụ về StatelessWidget:

class GreetingWidget extends StatelessWidget {
final String name;

const GreetingWidget({
super.key,
required this.name
});

@override
Widget build(BuildContext context) {
return Text('Hello, $name!');
}
}

Khi nào sử dụng StatelessWidget:

  • Hiển thị thông tin tĩnh
  • Widget chỉ phụ thuộc vào các tham số đầu vào
  • Không cần thay đổi UI theo thời gian
  • Không cần lưu trữ dữ liệu

2. StatefulWidget

StatefulWidget là widget có state (trạng thái). Nó có thể thay đổi trong quá trình sử dụng.

Đặc điểm của StatefulWidget:

  • Có state
  • Có thể thay đổi sau khi được tạo
  • Phù hợp cho UI động
  • Cần rebuild khi state thay đổi

Ví dụ về StatefulWidget:

class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});

@override
State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
int _count = 0;

void _increment() {
setState(() {
_count++;
});
}

@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: _increment,
child: const Text('Increment'),
),
],
);
}
}

Khi nào sử dụng StatefulWidget:

  • UI cần thay đổi theo thời gian
  • Cần lưu trữ dữ liệu
  • Có tương tác người dùng
  • Cần thực hiện các tác vụ bất đồng bộ

3. So sánh StatelessWidget và StatefulWidget

Đặc điểmStatelessWidgetStatefulWidget
StateKhông có
ImmutableKhông
Hiệu năngTốt hơnKém hơn
Sử dụngUI tĩnhUI động
CodeĐơn giảnPhức tạp hơn

4. Best Practices

4.1. Sử dụng StatelessWidget khi có thể

  • Ưu tiên sử dụng StatelessWidget nếu không cần state
  • Tách các phần UI tĩnh thành StatelessWidget riêng

4.2. Quản lý State hiệu quả

  • Chỉ lưu trữ state cần thiết
  • Sử dụng setState một cách hợp lý
  • Tránh rebuild không cần thiết

4.3. Tổ chức code

  • Tách biệt logic và UI
  • Sử dụng các widget có thể tái sử dụng
  • Đặt tên rõ ràng cho các widget

5. Ví dụ thực tế

5.1. StatelessWidget - ProductCard

class ProductCard extends StatelessWidget {
final String name;
final double price;
final String imageUrl;

const ProductCard({
super.key,
required this.name,
required this.price,
required this.imageUrl,
});

@override
Widget build(BuildContext context) {
return Card(
child: Column(
children: [
Image.network(imageUrl),
Text(name),
Text('\$$price'),
],
),
);
}
}

5.2. StatefulWidget - ShoppingCart

class ShoppingCart extends StatefulWidget {
const ShoppingCart({super.key});

@override
State<ShoppingCart> createState() => _ShoppingCartState();
}

class _ShoppingCartState extends State<ShoppingCart> {
final List<CartItem> _items = [];

void _addItem(CartItem item) {
setState(() {
_items.add(item);
});
}

void _removeItem(int index) {
setState(() {
_items.removeAt(index);
});
}

@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: _items.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_items[index].name),
trailing: IconButton(
icon: const Icon(Icons.delete),
onPressed: () => _removeItem(index),
),
);
},
);
}
}

Kết luận

Việc lựa chọn giữa StatelessWidget và StatefulWidget phụ thuộc vào yêu cầu của ứng dụng. StatelessWidget đơn giản và hiệu quả cho UI tĩnh, trong khi StatefulWidget linh hoạt hơn cho UI động. Hiểu rõ sự khác biệt giữa hai loại widget này sẽ giúp bạn xây dựng ứng dụng Flutter tốt hơn.


Tài liệu tham khảo:

Widget Tree và các loại Widget trong Flutter

· 4 min read

Flutter Widget Tree

Widget là thành phần cơ bản trong Flutter, mọi thứ bạn nhìn thấy trên màn hình đều là widget. Bài viết này sẽ giúp bạn hiểu rõ về cấu trúc Widget Tree và các loại widget phổ biến trong Flutter.

1. Widget Tree là gì?

Widget Tree là cấu trúc phân cấp của các widget trong ứng dụng Flutter. Mỗi widget có thể chứa các widget con, tạo thành một cây các widget.

MaterialApp
└── Scaffold
├── AppBar
│ └── Text
└── Column
├── Text
├── SizedBox
└── ElevatedButton
└── Text

Đặc điểm của Widget Tree:

  • Cấu trúc phân cấp
  • Widget cha chứa widget con
  • Mỗi widget có thể có nhiều widget con
  • Widget con kế thừa các thuộc tính từ widget cha

2. Các loại Widget cơ bản

2.1. StatelessWidget vs StatefulWidget

StatelessWidget

  • Widget không có state (trạng thái)
  • Không thể thay đổi sau khi được tạo
  • Phù hợp cho UI tĩnh
class GreetingWidget extends StatelessWidget {
final String name;

const GreetingWidget({super.key, required this.name});

@override
Widget build(BuildContext context) {
return Text('Hello, $name!');
}
}

StatefulWidget

  • Widget có state (trạng thái)
  • Có thể thay đổi trong quá trình sử dụng
  • Phù hợp cho UI động
class CounterWidget extends StatefulWidget {
const CounterWidget({super.key});

@override
State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
int _count = 0;

void _increment() {
setState(() {
_count++;
});
}

@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Count: $_count'),
ElevatedButton(
onPressed: _increment,
child: const Text('Increment'),
),
],
);
}
}

2.2. Các Widget phổ biến

Layout Widgets

  1. Container

    • Widget linh hoạt nhất
    • Có thể định dạng padding, margin, border, background
    Container(
    padding: const EdgeInsets.all(16),
    margin: const EdgeInsets.all(8),
    decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(8),
    ),
    child: const Text('Hello'),
    )
  2. Row và Column

    • Sắp xếp các widget theo chiều ngang/dọc
    Row(
    mainAxisAlignment: MainAxisAlignment.spaceBetween,
    children: [
    Text('Left'),
    Text('Center'),
    Text('Right'),
    ],
    )
  3. Stack

    • Xếp chồng các widget lên nhau
    Stack(
    children: [
    Image.network('url'),
    Positioned(
    bottom: 16,
    right: 16,
    child: Text('Overlay'),
    ),
    ],
    )

Input Widgets

  1. TextField

    • Nhập liệu văn bản
    TextField(
    decoration: InputDecoration(
    labelText: 'Username',
    hintText: 'Enter your username',
    ),
    )
  2. ElevatedButton

    • Nút bấm có hiệu ứng nổi
    ElevatedButton(
    onPressed: () {
    // Handle press
    },
    child: const Text('Click me'),
    )

Display Widgets

  1. Text

    • Hiển thị văn bản
    Text(
    'Hello World',
    style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    ),
    )
  2. Image

    • Hiển thị hình ảnh
    Image.network(
    'https://example.com/image.jpg',
    width: 200,
    height: 200,
    )

3. Quản lý State trong Widget Tree

3.1. Local State

  • Sử dụng setState trong StatefulWidget
  • Phù hợp cho state đơn giản, chỉ ảnh hưởng đến widget hiện tại

3.2. Global State

  • Sử dụng state management (Provider, Bloc, GetX)
  • Phù hợp cho state phức tạp, được chia sẻ giữa nhiều widget

4. Best Practices

  1. Tổ chức Widget Tree

    • Tách các widget phức tạp thành các widget nhỏ hơn
    • Sử dụng các widget có thể tái sử dụng
    • Tránh widget tree quá sâu
  2. Performance

    • Sử dụng const constructor khi có thể
    • Tránh rebuild không cần thiết
    • Sử dụng ListView.builder cho danh sách dài
  3. State Management

    • Chọn giải pháp state management phù hợp
    • Tránh prop drilling
    • Tách biệt logic và UI

Kết luận

Hiểu rõ về Widget Tree và các loại widget là nền tảng quan trọng trong phát triển Flutter. Với kiến thức này, bạn có thể xây dựng UI phức tạp và quản lý state hiệu quả.


Tài liệu tham khảo: