Flutter中經常可以看到Widget build(BuildContext context) {}
, Theme.of(context)
這些需要傳遞BuildContext的場景.
abstract class BuildContext {
/// The current configuration of the [Element] that is this [BuildContext].
Widget get widget;
/// The [BuildOwner] for this context. The [BuildOwner] is in charge of
/// managing the rendering pipeline for this context.
BuildOwner? get owner;
}
複製程式碼
BuildContext
是一個抽象類.
@override
StatelessElement createElement() {
// TODO: implement createElement
return super.createElement();
}
複製程式碼
Widget在構建的時候build
會呼叫createElement
.螢幕上顯示的檢視樹其實就是ElementTree.
widgetTree負責配置資訊,ElementTree負責顯示資訊,RenderObject負責渲染樹
abstract class StatelessWidget extends Widget {
const StatelessWidget({ Key? key }) : super(key: key);
@override
StatelessElement createElement() => StatelessElement(this);
@protected
Widget build(BuildContext context);
}
複製程式碼
createElement
呼叫StatelessElement(StatelessWidget widget)
,this就是widget.
/// An [Element] that uses a [StatelessWidget] as its configuration.
class StatelessElement extends ComponentElement {
/// Creates an element that uses the given widget as its configuration.
StatelessElement(StatelessWidget widget) : super(widget);
@override
StatelessWidget get widget => super.widget as StatelessWidget;
@override
Widget build() => widget.build(this);
@override
void update(StatelessWidget newWidget) {
super.update(newWidget);
assert(widget == newWidget);
_dirty = true;
rebuild();
}
}
複製程式碼
build()
呼叫了widget.build(this)
,this是StatelessElement
.
所以在widget進入檢視樹的時候,widget會傳給Element引用,Element通過widget呼叫widget的build(BuildContext context)
,傳入的context就是Element.
BuildContext = Element.BuildContext物件實際上就是Element物件.
of(context)方法
Theme.of(context).backgroundColor
Navigator.of(context).push
複製程式碼
在Flutter中經常會這樣操作,of(context)是Flutter開發的一種約定,從當前傳入的context向上遍歷尋找符合的state,是對跨元件獲取資料的一種封裝.
// Theme.of(context)
static ThemeData of(BuildContext context) {
final _InheritedTheme? inheritedTheme = context.dependOnInheritedWidgetOfExactType<_InheritedTheme>();
final MaterialLocalizations? localizations = Localizations.of<MaterialLocalizations>(context, MaterialLocalizations);
final ScriptCategory category = localizations?.scriptCategory ?? ScriptCategory.englishLike;
final ThemeData theme = inheritedTheme?.theme.data ?? _kFallbackTheme;
return ThemeData.localize(theme, theme.typography.geometryThemeFor(category));
}
複製程式碼