5. Widget tree
Widget Tree là cấu trúc đại diện
cho toàn bộ ứng dụng. tương tự
với DOM trong trang web.
Vai trò như Mục lục của cuốn sách,
widget tree thể hiện toàn bộ các
widget được dùng, vị trí và thứ tự
các widget được đặt.
8. 1- gọi hàm runApp(), Flutter build một Widget tree chứa các
widget.
2- Các element được tạo bởi các widget. Sau khi widget được
built, framework gọi hàm Widget.createElement(this).
Element Tree & Render Object
9. 3- Element gọi phương thức createRenderObject() để tạo ra các
RenderObject, các RenderObject này cấu thành nên Render Tree.
4- Mỗi một Element tham chiếu đến một Widget và một
RenderObject.
Element Tree & Render Object
10. Sao lại cần đến 3 tree?
Element không giữ cấu hình widget, nhưng có thể nhìn cấu hình
chi tiết thông qua việc tham chiếu đến widget tương ứng.
RenderObject chứa toàn bộ logic để rendering widget, nên nó khá
nặng nề để khởi tạo.
>> Khi widget trong tree thay đổi, Flutter sử dụng Elements để
so sánh widget mới với RenderObject đã tồn tại, -> nếu type của
widget không đổi, Flutter sẽ không tạo lại cái RenderObject nặng
nề đó, thay vào đó chỉ cập nhật mutable configuration.
Widget rất nhẹ để khởi tạo, nên nó sẽ được dùng để mô tả state
hiện tại.
11. Lưu ý
StateObject thực sự được quản lý
bởi element, không phải widget.
Flutter render dựa trên Elements và
state object, chứ nó không liên
quan gì đến widget.
12. Ví dụ Element và RenderObject
Đảo nút nhấn -> chỉ đảo text và
chức năng, màu nền không thay đổi
VÍ DỤ: https://bit.ly/337DUAd
13. Đa phần các Widget
extends từ Stateless
hoặc Stateful Widget
14. State
State - Trạng thái: đại diện cho dữ
liệu thay đổi trong vòng đời ứng
dụng.
📌 Khi dữ liệu của stateful thay
đổi, UI vẽ lại widget để phản ánh
state mới.
📎 Phần giao diện hiển thị chỉ đại
diện cho state tại một thời điểm,
thay đổi state -> thay đổi giao
diện.
15. Stateless Widget
Immutable – bất biến
Stateless Widget không
thể re-run build() khi
các thuộc tính của nó
thay đổi.
16. Không có state.
Không chấp nhận sự thay đổi
bên trong nó.
Đối với sự thay đổi từ
widget cha thì nó sẽ thụ
động thay đổi theo.
Stateless Widget
17. Build method
How to render a widget?
Flutter gọi tới build method
trong widget, nó trả về một
Widget object chứa thông tin
cấu hình để Flutter render.
18. Khi nào build method
Stateless được thực hiện ?
● Lần đầu tiên widget được thêm vào tree.
● Khi widget cha thay đổi.
● Khi các giá trị từ nguồn khác thay đổi
Ví dụ một Widget kế thừa sẽ phụ thuộc vào các thay đổi từ
nơi nó kế thừa
https://api.flutter.dev/flutter/widgets/StatelessWidget-
class.html
19. Stateful Widget
Thường được sử dụng khi giao diện cần thay đổi linh hoạt
● Người dùng tương tác gì đó trên giao diện
● Nhận dữ liệu từ nguồn khác
● Thay đổi theo thời gian
23. State và data trong Stateful
Thường được hiểu là dữ liệu bên trong widget
● Data trong Flutter Widget là immutable - bất biến.
Widget có thể lưu trữ data và data đó không đổi.
● Stateful Widget được liên kết với một State Object ,
Object này mới là nơi chứa dữ liệu mutable data ,
bản thân Widget không chứa mutable data.
⚠️ Stateful Widget có chứa mutable data ?
24. setState()
❓Tại sao cần gọi hàm
setState(() {}) trong Stateful
Widget mà không set thẳng
value?
Nếu không có setState(() {}),
Widget vẫn thay đổi giá trị
thuộc tính nhưng nó sẽ không
re-run build() method, vì vậy,
việc thay đổi đó ko phản ánh
lên màn hình. setState là như
một trigger thông báo cho
Flutter re-run build() method.
27. StatefulWidget lifecycle
createState(): Khi xây
dựng StatefulWidget, ngay
lập tức gọi
createdState().
initState(): Để khởi tạo
state, chỉ được gọi một
lần khi widget được tạo.
setState như một trigger
thông báo cho Flutter re-
run build() method
28. StatefulWidget lifecycle
didChangeDependencies : có
thể được gọi một lần sau
initState, cũng có thể
được gọi lại trong
Lifecycle
Tại thời điểm này, State
được coi là "dirty", đó là
cách Flutter theo dõi
những widget nào cần được
rebuild. Bất cứ khi nào
một state object cần
rebuild, nó tự đánh dấu là
"dirty".
29. StatefulWidget lifecycle
didChangeDependencies : có
thể được gọi một lần sau
initState, cũng có thể
được gọi lại trong
Lifecycle
Tại thời điểm này, State
được coi là "dirty", đó là
cách Flutter theo dõi
những widget nào cần được
rebuild. Bất cứ khi nào
một state object cần
rebuild, nó tự đánh dấu là
"dirty".
30. StatefulWidget lifecycle
build() xây dựng đầy đủ
state object.
sau build(), state được
đánh dấu là "clean".
-> lifecycle hoàn thành
một “single track”.
31. StatefulWidget lifecycle
setState() đánh dấu state ở trạng
thái “dirty”, thực hiện re-run
lại phương thức build()
Một widget cha ở trên có thể yêu
cầu xây dựng lại widget đang thao
tác.
Nếu vị trí sẽ được rebuild với
cùng loại và khóa widget, thì sẽ
gọi didUpdateWidget(old widget).
state cũng bị đánh dấu là “dirty”
35. Build Context
Mọi widget trong Flutter được tạo từ
một build() method
và method này đều lấy BuildContext làm
đối số (argument).
36. Build Context
Context tham chiếu đến vị trí của
Widget trong cấu trúc tree.
Một context chỉ thuộc về một widget.
Mỗi Widget có phương thức build() và
context riêng.
BuildContext là cha của widget được
trả về.
37. Build Context
Ví dụ: https://bit.ly/357pwtc
Ví dụ về
BuildContext tham
chiếu đến vị trí
của widget
WithBuildContext
-> từ đó dùng
method ancestor lấy
widget cha (cụ thể
là Column)
-> hoặc lấy các
widget xung quanh
38. Build Context
Nếu một widget chứa
các widget con,
context của widget cha
sẽ trở thành parent
context của các
context widget con.
Trên một cây thành phần Widget tiêu biểu, khi setState() được gọi từ các thành phần cha, nó sẽ vẽ lại tất cả thành phần con cháu. Điều này gây ra sự cập nhật không cần thiết cho những thành phần con không thay đổi trạng thái, nói đơn giản hơn là bạn không thể chỉ định một thành phần con nào đó để cập nhật lại trạng thái.
BLoC Architecture, MobX, Scoped Model và Redux.