赞
踩
从用户操作到GPU
构建:从Widget到Element
布局和渲染
Platform embedding
=================================================================
本文总结Flutter架构概览,包含其设计层面的核心原则以及概念。
Flutter是一个跨平台的UI工具集,它允许在各种操作系统上复用相同的代码,同时应用程序直接与底层平台交互,避免了不同平台视图的差异,同时也让开发者能够在不同平台上都能交付拥有原生体验的高性能应用。
开发阶段,FLutter应用会在一个VM(程序虚拟机)中运行,从而可以保留状态且无需重新编译的情况下,热重载相关的更新。对于发行版(release),Flutter程序会直接编译错机器码,或者针对Web平台的JavaScript。
概览分为以下几个部分:
分层模型:Flutter的构成要素
响应式用户界面:Flutter用户界面开发的核心概念
widgets介绍:构建Flutter用户界面的基石
渲染过程:Flutter如何将界面布局转化为像素
平台嵌入层的概念:让Flutter应用可以再移动端以及桌面端操作系统执行的代码
==================================================================
Flutter被设计为一个可扩展的分层系统。它可以被看做是各个独立的组件系列合集,上层的组件各自依赖下层的组件。组件无法越权访问底层的内容,并且框架层的各个部分都是可选且可替代。
对于底层操作系统而言,Flutter应用程序的包装方式与其他原生应用相同。在每一个平台上,都回去包含一个特定的嵌入层,从而提供一个程序入口,程序由此可以与底层操作系统进行协调,访问诸如Surface渲染,辅助功能和输入等等服务,并且管理时间循环队列。该嵌入层采用了适合当前平台语言编写,例如Android使用的是Java/C++,IOS和MacOSSierra使用的是OC和OC++,Windows和Linux使用的是C++,Flutter代码可以通过嵌入层,以模块方式集成到现有的应用中,也可以作为应用的主体。Flutter本身包含了各个常见平台的嵌入层,同时也存在一些其他的嵌入层。
Flutter引擎毫无疑问是Flutter的核心,它主要是C++编写,并提供了Flutter应用所需要的原语。当需要绘制新的一帧的内容时,引擎将负责对需要合成的场景进行栅格化。它提供了Flutter核心API的底层实现,包括图形(通过Skia)、文本布局、文件以及网络IO、辅助功能支持、插件架构和Dart运行环境以及编译环境的工具链。
引擎将C++ 代码包装成Dart代码,通过dart:ui暴露给Flutter框架层。该库暴露了最底层的原语,包括用于驱动图形输入、图形、和文本渲染的子系统的类。
通常,开发者可以通过Flutter Framework与Flutter进行交互,该Framework提供了以Dart语音编写的现代响应式框架。它包括由一系列层组成的一组丰富的平台,布局和基础库。从下层到上层,依次有:
基础的 foundational 类及一些基层之上的构建块服务,如 animation、 painting 和 gestures,它们可以提供上层常用的抽象。
渲染层 用于提供操作布局的抽象。有了渲染层,你可以构建一棵可渲染对象的树。在你动态更新这些对象时,渲染树也会自动根据你的变更来更新布局。
widget 层 是一种组合的抽象。每一个渲染层中的渲染对象,都在 widgets 层中有一个对应的类。此外,widgets 层让你可以自由组合你需要复用的各种类。响应式编程模型就在该层级中被引入。
Material 和 Cupertino 库提供了全面的 widgets 层的原语组合,这套组合分别实现了 Material 和 iOS 设计规范。
Flutter 框架相对较小,因为一些开发者可能会使用到的更高层级的功能已经被拆分到不同的软件包中,使用 Dart 和 Flutter 的核心库实现,其中包括平台插件,例如 camera 和 webview;与平台无关的功能,例如 characters、 http 和 animations。还有一些软件包来自于更为宽泛的生态系统中,例如 应用内支付、 Apple 认证 和 Lottie 动画。
该概览的其余部分将从 UI 开发的响应式范例开始,浏览各个构建层。而后,我们会讲述 widgets 如何被组织,并转换成应用程序的渲染对象。同时我们也会讲述 Flutter 如何在平台层面与其他代码进行交互,最终,我们会对目前 Flutter 对于 Web 平台的支持与其他平台的异同做一个总结。
======================================================================
Flutter 是一个响应式的且伪声明式的 UI 框架,开发者负责提供应用状态与界面状态之间的映射,框架则在运行时将应用状态的更改更新到界面上。在大部分传统的 UI 框架中,界面的初始状态通常会被一次性定义,然后,在运行时根据用户代码分别响应事件进行更新。
Flutter 与其他响应式框架类似,采用了显式剥离基础状态和用户界面的方式,来解决这一问题。你可以通过 React 风格的 API,创建 UI 的描述,让框架负责通过配置优雅地创建和更新用户界面。
在 Flutter 里,widgets(类似于 React 中的组件)是用来配置对象树的不可变类。这些 widgets 会管理单独的布局对象树,接着参与管理合成的布局对象树。 Flutter 的核心就是一套高效的遍历树的变动的机制,它会将对象树转换为更底层的对象树,并在树与树之间传递更改。
build()
是将状态转化为 UI 的方法,widget 通过重写该方法来声明 UI 的构造。build()
方法在框架需要时都可以被调用(每个渲染帧可能会调用一次),从设计角度来看,它应当能够快速执行且没有额外影响的。这样的实现设计依赖于语言的运行时特征(特别是对象的快速实例化和清除)。幸运的是,Dart 非常适合这份工作。
======================================================================
应用额如前所述,FLutter强调以widgets作为组成单位。Widgets是构建Flutter应用界面的基础块,每个widget都是一部分不可变的UI声明。
Widgets通过布局组合形成一种层次结构关系。每个Widget都是嵌套在其父级的内部,并可以通过父级接收上下文。从根布局(托管Flutter应用的容器,通常是MaterialApp或者CupertinoApp)开始,自上而下就是这样的结构,如下面实例;
import ‘package:flutter/material.dart’;
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text(‘My Home Page’),
),
body: Center(
child: Builder(
builder: (BuildContext context) {
return Column(
children: [
const Text(‘Hello World’),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
print(‘Click!’);
},
child: const Text(‘A button’),
),
],
);
},
),
),
),
);
}
}
在上面的代码中,所有的实例化的类都是widgets。
应用会根据事件交互,通知框架替换层级中的旧的widget为新的widget,最后框架会比较新旧widgets,高效的更新用户界面。
Flutter拥有其自己的UI控制实现,而不是由系统自带的方法进行托管:例如,IOS的Switch控件和Android的选择控件都有一个Dart实现。
这样的实现有几个优势:
提供了诬陷的扩展性。
Flutter可以直接合成所有的场景,而无需在Flutter与原生平台之间来回的切换,从而避免了明显的性能瓶颈。
将应用的行为与操作系统的依赖解耦。
Widget通常由更小的且用途单一的widgets组合而成,提供更强大的功能。
在设计的时候,相关的概念设计已尽可能地少量存在,而通过大量的内容进行填充。eg,Flutter在widgets层中使用了相同的概念(一个Widget)来表示屏幕上的绘制、布局(位置和大小)、用户交互、状态管理、主题、动画以及导航。在动画层,Animation和Tween这对概念组合,涵盖了大部分的设计空间。在渲染层,RenderObject用来描述布局、绘制、触摸判断以及可访问性。在这些场景中,最终对于包含的内容都很多:有数百个widgets和Render objects,以及数十种的动画和补间类型。
类的层次结构是有意的浅而广,以最大限度的增加可能的组合数量,重点放在小的,可组合的widget上,确保每个widget都能横好的完成一件事情。核心功能均被抽象,甚至像编剧和对齐这样的基础功能,都被实现为单独的组件,而不是内置于核心中。(这样的实现也与传统的API形成了对比,类似于边距这样的功能通常都内置在了每个组件的公共核心内,Flutter中的widget则不同。)因此,如果你需要讲一个widget居中,预期调整Align这样的属性,不如将他包裹在一个Center widget内。
Flutter中包含了边距,对齐,行,列和网格系列的widgets。这些布局类型的widgets自身没有视觉内容,而只用于控制其他的widgets的部分布局条件。Flutter也包含了以这种组合方法组成的实用性widgets。
例如,一个常用的widget Container,是由几个widget组合而成,包含了布局、绘制、定位和大小的功能。更具体地说,Container是由LimitedBox、ConstrainedBox、Align、Padding、DecoratedBox和Transform组合而成的,你也可以通过查看源码看到这些组合。Flutter 有一个典型的特征,即你可以深入到任意一个 widget,查看其源码。因此,你可以通过同样的方式组合其他的 widgets,也可以参考 Container
来创建其他的 widget,而不需要继承 Container
来实现自定义的效果。
先前提到,可以通过重写build()方法,返回一个新的元素树,来定义视觉展示。这棵树用更为具体的术语表示了widget在UI中的部分。例如,工具栏widget的build方法可能会返回水平布局,其中可能包含了一些文字,各种各样的按钮。根据需要,框架会递归请求每个widget进行构建,直到整棵树都被具体的可渲染的对象描述为止。然后框架会将可渲染的对象缝合在一起,组成可渲染的对象树。
Widget的build方法应该是没有副作用的。每当一个方法要求构建市,widget都应当能返回一个widget的元素树,与先签返回的widget也没有关联。框架会根据渲染对象树来确定哪些构建方法需要被调用,这是一响略显繁重的工作。
每个渲染帧,Flutter都可以根据变换的状态,调用build()方法重建部分UI。因此,保证build方法轻量且能够快速返回widget是非常关键的,繁重的计算工作应该通过一些异步的方法来完成,然后作为构建方法build的一部分存储。
尽管这样的实现看起来不够成熟,但是这样的自动对比方法非常有效,可以实现高性能的交互应用。同时,以这种方式设计的build方法,将重点放在widget组合的声明上,从而简化了代码,而不是以一种状态去更新另一种状态这样的复杂过程。
那么,在众多的widget都持有状态的情况下,系统中的状态是如何被传递和管理的呢?
与其他类相同,你可以通过widget的构造函数来初始化数据,如此一来build()方法可以确保子widget使用其所需要的数据进行实例化:
@override
Widget build(BuildContext context) {
return ContentWidget(importantState);
}
然而,随着widget树层级的逐渐增加加深,依赖树结构上下传递状态信息会变得十分麻烦。这时,第三张类型的widget——InheritedWidget,提供了一种从共享的祖先节点获取数据的简易办法。你可以使用InheritedWidget创建包含状态的widget,该widget会将一个共同的祖先节点包裹在widget树中,如下:
现在,当ExamWidget或者GradeWIdget对象需要获取StudentState的数据时,可以直接使用以下方式:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
写到这里也结束了,在文章最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的点击这里>Android IOC架构设计免费获取。
群内还有免费的高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。
最后放上一个小小的福利,以下为小编自己在学习过程中整理出的一个学习思路及方向,从事互联网开发,最主要的是要学好技术,而学习技术是一条慢长而艰苦的道路,不能靠一时激情,也不是熬几天几夜就能学好的,必须养成平时努力学习的习惯,更加需要准确的学习方向达到有效的学习效果。
由于内容较多就只放上一个大概的大纲,需要更及详细的学习思维导图的点击这里>Android IOC架构设计免费获取。
群内还有免费的高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术资料,并且还有技术大牛一起讨论交流解决问题。**
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。