Widget build(BuildContext context) {
final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
TextStyle effectiveTextStyle = style;
if (style == null || style.inherit)
effectiveTextStyle = defaultTextStyle.style.merge(style);
if (MediaQuery.boldTextOverride(context))
effectiveTextStyle = effectiveTextStyle.merge(const TextStyle(fontWeight: FontWeight.bold));
Widget result = RichText( ---->Text原来是通过RichText这个widget来构建树
textAlign: textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start,
textDirection: textDirection, // RichText uses Directionality.of to obtain a default if this is null.
locale: locale, // RichText uses Localizations.localeOf to obtain a default if this is null
softWrap: softWrap ?? defaultTextStyle.softWrap,
overflow: overflow ?? defaultTextStyle.overflow,
textScaleFactor: textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
maxLines: maxLines ?? defaultTextStyle.maxLines,
strutStyle: strutStyle,
text: TextSpan(
style: effectiveTextStyle,
text: data,
children: textSpan != null ? [textSpan] : null,
),
);
…
继续往RichText
里面看:
…
@override
RenderParagraph createRenderObject(BuildContext context) {
assert(textDirection != null || debugCheckHasDirectionality(context));
//返回RenderParagraph widget
return RenderParagraph(text,
textAlign: textAlign,
textDirection: textDirection ?? Directionality.of(context),
softWrap: softWrap,
overflow: overflow,
textScaleFactor: textScaleFactor,
maxLines: maxLines,
strutStyle: strutStyle,
locale: locale ?? Localizations.localeOf(context, nullOk: true),
);
}
…
发现最终它会返回RenderParagraph
widget,继续往里看:
class RichText extends LeafRenderObjectWidget {
}
可以发现RichText
继承LeafRenderObjectWidget
,继续往下看:
//用于配置RenderObject子类的RenderObjectWidgets的超类,没有孩子,也就是没有字节点(child)
abstract class LeafRenderObjectWidget extends RenderObjectWidget {
const LeafRenderObjectWidget({ Key key }) : super(key: key);
//构建出类型是LeafRenderObjectElement
@override
LeafRenderObjectElement createElement() => LeafRenderObjectElement(this);
}
可以看到LeafRenderObjectWidget
是抽象类,并且继承了RenderObjectWidget
,继续往下看:
/// RenderObjectWidgets provide the configuration for [RenderObjectElement]s,
/// which wrap [RenderObject]s, which provide the actual rendering of the
/// application.
//上面注释是:RenderObjectWidgets向[RenderObjectElement]提供了配置信息,包装了[RenderObject],在应用程序了提供了实际的渲染
abstract class RenderObjectWidget extends Widget {
const RenderObjectWidget({ Key key }) : super(key: key);
//创建element
@override
RenderObjectElement createElement();
//创建RenderObject
@protected
RenderObject createRenderObject(BuildContext context);
//更新RenderObject
@protected
void updateRenderObject(BuildContext context, covariant RenderObject renderObject) { }
//卸载RenderObject
@protected
void didUnmountRenderObject(covariant RenderObject renderObject) { }
}
由注释可以知道RenderObject
才是绘制UI背后的真正对象,那下面继续简单跟踪:
3.RenderObjectWidget
先看看RenderObjectWidget
继承关系:
看看文档的一一介绍:
3.1.SingleChildRenderObjectWidget
官方文档写的很清楚: 是RenderObjectWidgets
的超类,用于配置有单个孩子的RenderObject
子类(为子类提供存储,实际不提供更新逻辑),并列了具体的实际widget
,如常用的Align、ClipRect、DecoratedBox都是属于这类。
3.2.MultiChildRenderObjectWidget
同样也是RenderObjectWidgets
的超类,用于配置有单个children(也就是多个child)的RenderObject
子类,如Flex、Flow、Stack都属于这类。
3.3.LeafRenderObjectWidget
同样也是RenderObjectWidgets
的超类,用于配置没有孩子的RenderObject
子类,如:RichText(平时的Text)、RawImage、Texture等。 这里总结一下:
SingleChildRenderObjectWidget
用作只有一个child的widget
。MultiChildRenderObjectWidget
用作有children(多个孩子)的widget
。LeafRenderObjectWidget
用作没有child的widget
。RenderObjectWidget
定义了创建,更新,删除RenderObject的方法,子类必须实现,RenderObject
是最终布局、UI渲染的实际对象。
那么假如我现在界面上,假如布局如下:
那么渲染流程如下:
这时候会想:为什么要加中间层Element
呢,不直接由Widget
直接转换成RendObject
不是直接更好么?其实并不是这样的。首先知道Flutter是响应式框架,