1.6 组件渲染过程简述
通过前一节的学习,读者一定对Flutter中3棵树各自的作用有了一定的了解,但对Flutter内部创建这3棵树的意义并不完全理解,因为所有的功能貌似仅用一棵树就能实现,创建3棵树只会加大工作量。本节结合计数器应用对这3棵树再做一个简要的分析。对于组件树中存放计数值的Text组件,在开发者指定显示的属性内容为_counter后它就不能再更新了。因此,为了在页面中改变这个状态值,必须调用_MyHomePageState的setState()函数通知与它对应的元素将状态更新为最新的计数值。下面的_incrementCounter()就是单击“+”按钮后调用的函数。
void _incrementCounter() {
setState(() {
_counter++;
});
}
这段代码就让元素意识到状态已经改变,因为在setState()函数内部会将组件树中MyHomePage以下的所有组件标记为可更新状态,这时,元素就可以开始使对应的RenderObject将那些可更新组件用最新状态值渲染出来。
另外,还值得我们继续深究的就是Flutter中渲染树是如何将最新状态下的实际组件渲染在屏幕中的。图1.18揭示了Flutter中组件的渲染流程。
图1.18 Flutter中组件的渲染流程
从图1.18可以看出来,始终由用户触发重新渲染UI的操作。用户可能会单击页面中的某个按钮,调用setState()函数,然后就会触发页面更新,接下来就会执行过渡动画,在动画执行期间,Flutter将会一直更新,直到渲染完成。构建组件的过程就是Flutter构建上一节介绍的3棵树的过程。构建完成之后,Flutter就会通过RenderObject树上的RenderObject节点执行真正的渲染工作。
RenderObject依赖在代码中配置的组件,它会根据已经设置的属性完成接下来的布局(layout)、绘制(paint)以及合成(composite)操作。其中,布局操作会使用布局约束等原理计算各部分组件的实际大小,这部分内容将在第4章详细介绍;绘制过程就是根据配置的视图数据将组件的内容绘制在屏幕当中;合成就是将各部分的视图层合并在一起。
在日常开发中,我们只需要在代码中针对各个组件的特性配置好组件树,其余的工作可以直接交给Flutter框架层去实现,因此,我们大部分时间可能花在了解各种组件的特性与使用方法上。理解这部分内容后对我们之后学习常用组件有很大的帮助。在以后的学习中,我们应当用不同的眼光去看待我们所建立的布局和组件。在本书后面的内容中,我们会继续探究这部分内容,让读者更加深入地理解这3棵树。