Flutter学习之视图体系,2018年安卓面试题

本文深入解析Flutter的视图体系,从RenderObjectWidget的三大类别到UI渲染流程,包括SingleChildRenderObjectWidget、MultiChildRenderObjectWidget和LeafRenderObjectWidget的使用场景。通过分析启动到显示的过程,揭示WidgetsFlutterBinding、attachRootWidget和scheduleWarmUpFrame在构建和展示UI中的作用,帮助理解Flutter的响应式框架设计和提高页面渲染效率的策略。
摘要由CSDN通过智能技术生成

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),
);
}

发现最终它会返回RenderParagraphwidget,继续往里看:

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继承关系:

image.png

看看文档的一一介绍:

3.1.SingleChildRenderObjectWidget

image.png

官方文档写的很清楚: 是RenderObjectWidgets的超类,用于配置有单个孩子的RenderObject子类(为子类提供存储,实际不提供更新逻辑),并列了具体的实际widget,如常用的Align、ClipRect、DecoratedBox都是属于这类。

3.2.MultiChildRenderObjectWidget

image.png

同样也是RenderObjectWidgets的超类,用于配置有单个children(也就是多个child)的RenderObject子类,如Flex、Flow、Stack都属于这类。

3.3.LeafRenderObjectWidget

image.png

同样也是RenderObjectWidgets的超类,用于配置没有孩子的RenderObject子类,如:RichText(平时的Text)、RawImage、Texture等。 这里总结一下:

  • SingleChildRenderObjectWidget用作只有一个child的widget
  • MultiChildRenderObjectWidget用作有children(多个孩子)的widget
  • LeafRenderObjectWidget用作没有child的widget
  • RenderObjectWidget定义了创建,更新,删除RenderObject的方法,子类必须实现,RenderObject是最终布局、UI渲染的实际对象。

那么假如我现在界面上,假如布局如下:

image.png

那么渲染流程如下:image.png

这时候会想:为什么要加中间层Element呢,不直接由Widget直接转换成RendObject不是直接更好么?其实并不是这样的。首先知道Flutter是响应式框架,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值