StatefulWidget vs StatelessWidget.
StatelessWidget - Một widget không yêu cầu trạng thái có thể thay đổi.
Tiện ích con không trạng thái là một tiện ích mô tả một phần của giao diện người dùng bằng cách xây dựng một nhóm các tiện ích con khác mô tả giao diện người dùng cụ thể hơn. Quá trình xây dựng tiếp tục đệ quy cho đến khi mô tả giao diện người dùng hoàn toàn cụ thể (ví dụ: bao gồm hoàn toàn RenderObjectWidgets, mô tả RenderObjects cụ thể).
Các stateless
widget hữu ích khi một phần của giao diện người dùng mà bạn mô tả không phụ thuộc vào bất cứ điều gì khác hơn là thông tin cấu hình trong đối tượng chính nó và
BuildContext trong đó các phụ tùng được thổi phồng. Đối với các thành phần có thể thay đổi động, ví dụ như do có trạng thái điều khiển đồng hồ bên trong hoặc tùy thuộc vào một số trạng thái hệ thống, hãy cân nhắc sử dụng
StatefulWidget
.
class GreenFrog extends StatelessWidget {
const GreenFrog({ Key key }) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(color: const Color(0xFF2DBD3A));
}
}
StatefulWidget - Một tiện ích có trạng thái có thể thay đổi.
- Các widget trạng thái rất hữu ích khi một phần của giao diện người dùng mà bạn đang mô tả có thể thay đổi động.
Khi Flutter xây dựng một StatefulWidget
, nó sẽ tạo ra một đối tượng State. Đối tượng này là nơi chứa tất cả trạng thái có thể thay đổi cho tiện ích con đó.
Khái niệm nhà nước được định nghĩa bởi hai điều:
1) Dữ liệu được tiện ích con sử dụng có thể thay đổi.
2) Dữ liệu không thể được đọc đồng bộ khi tiện ích con được tạo. (Tất cả trạng thái phải được thiết lập vào thời điểm phương thức xây dựng được gọi).
Vòng đời StatefulWidget
Vòng đời có các bước đơn giản sau:
- createState () - Khi Flutter được hướng dẫn xây dựng một StatefulWidget, nó sẽ gọi ngay lập tức
createState()
.
Tạo trạng thái có thể thay đổi cho tiện ích con này tại một vị trí nhất định trên cây.
Các lớp con nên ghi đè phương thức này để trả về một phiên bản mới được tạo của lớp con Trạng thái được liên kết của chúng:
@override
_MyState createState() => _MyState();
- mount == true - Tất cả các widget đều có thuộc
this.mounted
tính bool . Nó trở thành sự thật khi buildContext
được chỉ định. Đó là một lỗi setState
khi gọi khi một tiện ích được ngắt kết nối. Cho dù đối tượng Trạng thái này hiện đang ở trong một cây.
Sau khi tạo một đối tượng State và trước khi gọi initState
, framework "gắn kết" đối tượng State bằng cách liên kết nó với a
BuildContext
. Đối tượng State vẫn được gắn kết cho đến khi khung công tác
gọi dispose()
, sau thời gian đó, khung công tác sẽ không bao giờ yêu cầu
đối tượng Trạng thái xây dựng lại.
Đó là một lỗi khi gọi setState trừ khi mount là true.
bool get mounted => _element != null;
- initState () - Đây là phương thức đầu tiên được gọi khi widget được tạo (tất nhiên là sau hàm tạo lớp).
initState
được gọi một lần và chỉ một lần. Nó phải gọisuper.initState().
Khởi tạo dữ liệu dựa trên BuildContext cụ thể cho phiên bản widget đã tạo.
Khởi tạo các thuộc tính dựa trên các widget 'cha' này trong cây.
Đăng ký Luồng ChangeNotifiers
hoặc bất kỳ đối tượng nào khác có thể thay đổi dữ liệu trên tiện ích con này.
@override
initState() {
super.initState();
cartItemStream.listen((data) {
_updateWidget(data);
});
}
- didChangeDependencies () - Được gọi khi một phụ thuộc của đối tượng State này thay đổi.
Phương thức này cũng được gọi ngay sau đó initState
. Nó là an toàn để gọi BuildContext.inheritFromWidgetOfExactType
từ phương pháp này.
Các lớp con hiếm khi ghi đè phương thức này vì khung công tác luôn gọi xây dựng sau khi thay đổi phụ thuộc. Một số lớp con ghi đè phương thức này vì chúng cần thực hiện một số công việc tốn kém (ví dụ: tìm nạp mạng) khi các phụ thuộc của chúng thay đổi và công việc đó sẽ quá tốn kém để thực hiện cho mọi bản dựng.
@protected
@mustCallSuper
void didChangeDependencies() { }
- build () - Mô tả một phần của giao diện người dùng được đại diện bởi widget.
Khuôn khổ gọi phương thức này trong một số trường hợp khác nhau:
- Sau khi gọi
initState
.
- Sau khi gọi
didUpdateWidget
.
- Sau khi nhận được cuộc gọi đến
setState
.
- Sau khi sự phụ thuộc của đối tượng Trạng thái này thay đổi (ví dụ: một InheritedWidget được tham chiếu bởi các thay đổi bản dựng trước đó).
- Sau khi gọi hủy kích hoạt và sau đó chèn lại đối tượng Trạng thái vào cây ở vị trí khác.
Khuôn khổ thay thế cây con bên dưới tiện ích con này bằng tiện ích con được trả về bởi phương thức này, bằng cách cập nhật cây con hiện có hoặc bằng cách xóa cây con và thổi phồng cây con mới, tùy thuộc vào việc tiện ích con được trả về bởi phương thức này có thể cập nhật gốc của cây con hiện có hay không , được xác định bằng cách gọi
Widget.canUpdate
.
Thông thường, các triển khai trả về một nhóm widget mới được tạo được cấu hình với thông tin từ phương thức khởi tạo của widget này, BuildContext đã cho và trạng thái bên trong của đối tượng State này.
@override
Widget build(BuildContext context, MyButtonState state) {
... () { print("color: $color"); } ...
}
- didUpdateWidget () - Được gọi bất cứ khi nào cấu hình widget thay đổi.
Nếu widget cha xây dựng lại và yêu cầu vị trí này trong bản cập nhật cây hiển thị một widget mới có cùng loại thời gian chạy và Widget.key, thì khung công tác sẽ cập nhật thuộc tính widget của đối tượng State này để tham chiếu đến widget mới và sau đó gọi nó với widget trước đó làm đối số.
Ghi đè phương thức này để phản hồi khi tiện ích thay đổi (ví dụ: để bắt đầu hoạt ảnh ngầm).
Khung công tác luôn gọi xây dựng sau khi gọi didUpdateWidget, có nghĩa là bất kỳ lệnh gọi nào đến setState trong didUpdateWidget đều dư thừa.
@mustCallSuper
@protected
void didUpdateWidget(covariant T oldWidget) { }
- setState () - Bất cứ khi nào bạn thay đổi trạng thái bên trong của một đối tượng State, hãy thực hiện thay đổi trong một hàm mà bạn chuyển đến
setState
:
Việc gọi setState thông báo cho khung rằng trạng thái bên trong của đối tượng này đã thay đổi theo cách có thể ảnh hưởng đến giao diện người dùng trong cây con này, điều này khiến khung lên lịch xây dựng cho
đối tượng Trạng thái này.
Nếu bạn chỉ thay đổi trạng thái trực tiếp mà không gọi setState , khung công tác có thể không lên lịch xây dựng và giao diện người dùng cho cây con này có thể không được cập nhật để phản ánh trạng thái mới.
setState(() { _myState = newValue });
- hủy kích hoạt () - Hủy kích hoạt được gọi khi Trạng thái bị xóa khỏi cây, nhưng nó có thể được lắp lại trước khi kết thúc thay đổi khung hiện tại. Phương thức này tồn tại về cơ bản vì các đối tượng Trạng thái có thể được di chuyển từ điểm này sang điểm khác.
- Khuôn khổ gọi phương thức này bất cứ khi nào nó loại bỏ đối tượng Trạng thái này khỏi cây. Trong một số trường hợp, khung công tác sẽ chèn lại đối tượng State vào một phần khác của cây (ví dụ: nếu cây con chứa đối tượng State này được ghép từ vị trí này trong cây sang vị trí khác). Nếu điều đó xảy ra, khung công tác sẽ đảm bảo rằng nó gọi xây dựng để cho đối tượng Trạng thái cơ hội thích nghi với vị trí mới của nó trong cây. Nếu khung công tác chèn lại cây con này, nó sẽ làm như vậy trước khi kết thúc khung hoạt hình mà cây con đã bị xóa khỏi cây. Vì lý do này, các đối tượng State có thể trì hoãn việc giải phóng hầu hết các tài nguyên cho đến khi khuôn khổ gọi phương thức xử lý của chúng.
Điều này hiếm khi được sử dụng.
@protected
@mustCallSuper
void deactivate() { }
- dispose () - Được gọi khi đối tượng này bị xóa vĩnh viễn khỏi cây.
Khuôn khổ gọi phương thức này khi đối tượng Trạng thái này sẽ không bao giờ xây dựng lại. Sau khi khuôn khổ gọi dispose()
, đối tượng State được coi là không gắn kết và thuộc tính được gắn kết là sai. Đó là một lỗi khi gọi setState tại thời điểm này. Giai đoạn này của vòng đời là giai đoạn cuối: không có cách nào để đánh giá lại một đối tượng Trạng thái đã bị xử lý.
Các lớp con nên ghi đè phương thức này để giải phóng bất kỳ tài nguyên nào được giữ lại bởi đối tượng này (ví dụ: dừng mọi hoạt ảnh đang hoạt động).
@protected
@mustCallSuper
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() { _debugLifecycleState = _StateLifecycle.defunct; return true; }());
}
Để biết thêm thông tin, hãy vào đây tại đây , tại đây