flutter开发技术,Flutter架构

为什么Flutter开发APP性能最接近原生,前端程序员请关注

Flutter是谷歌公司推出的跨终端的开发框架,支持Android、iOS和WEB终端。1.0版在2018年12月5日发布,目前的最新版本是1.5,它采用的开发语言是Dart,Dart也是谷歌开发的计算机编程语言,语法类似C,是编译型语言:

创新互联建站主要为客户提供服务项目涵盖了网页视觉设计、VI标志设计、全网营销推广、网站程序开发、HTML5响应式网站建设公司成都做手机网站、微商城、网站托管及成都企业网站维护、WEB系统开发、域名注册、国内外服务器租用、视频、平面设计、SEO优化排名。设计、前端、后端三个建站步骤的完善服务体系。一人跟踪测试的建站服务标准。已经为岗亭行业客户提供了网站建设服务。

hello world例子,打印字符串“Hello World!”:

1、没有桥接层

React Native、Weex等技术都是跨终端的框架,然而性能跟原生App存在很大差距。这是由于它们的工作原理决定的:

React Native、Weex等技术多了一个桥接层,所以界面渲染会慢一些,由于UI渲染非常频繁,想要不卡顿,基本上比较难,性能和用户体验跟原生代码有差距。而这恰恰是Flutter的优势所在:

Dart可以被编译成不同平台的本地代码,让Flutter不通过桥接层直接跟平台通信,自然性能会快一些。

2、编译执行

JavaScript是解释执行的,Dart是编译执行的,性能谁好一目了然。

3、Flutter Engine虚拟机

Flutter是依靠Flutter Engine虚拟机在iOS和Android上运行的,Flutter Engine使用C/C++编写,开发人员通过Flutter框架直接和API在内部进行交互,所以具有输入低延迟和UI渲染高帧速率的特点。除了这特点之外,Flutter还提供了自己的小部件,Flutter小部件是使用从React获取灵感的现代框架构建的。 中心思想是您使用小部件构建UI。

窗口小部件根据其当前配置和状态描述了它们的视图。 当窗口小部件的状态发生更改时,窗口小部件会重建其描述,框架将根据前面的描述进行区分,以确定底层呈现树从一个状态转换到下一个状态所需的最小更改。可以直接在OS平台提供的画布上进行描绘,也就是一些核心类库直接放到虚拟机里面,调用起来更快。

从它的系统结构可以看出,类似安卓的ART(Android Run Time)虚拟机,同样采用AOT(Ahead of TIme)技术,会在APP安装时就编译成机器语言,不再解释执行,从而优化了APP运行的性能。

4、自带渲染引擎

Flutter使用谷歌自己的Skia渲染引擎,而Android系统自带Skia引擎,iOS平台上Flutter也会把Skia引擎打包到APP中,从而实现了高效渲染。而React Native通过桥接层访问原生UI,操作频繁就容易出性能问题。

综合所述,Flutter 是性能最接近原生代码 的一种开发框架,未来也会是构建谷歌Fuchsia应用的主要方式,前途不可限量,唯一的问题就是需要学习一门新的语言:Dart,而有Java或者C#语言基础的程序员会比较容易学习。

Flutter浪潮下的音视频研发探索

文/陈炉军

整理/LiveVideoStack

大家好,我是阿里巴巴闲鱼事业部的陈炉军,本次分享的主题是Flutter浪潮下的音视频研发探索,主要内容是针对闲鱼APP在当下流行的跨平台框架Flutter的大规模实践,介绍其在音视频领域碰到的一些困难以及解决方案。

分享内容主要分为四个方面,首先会对Flutter有一个简单介绍以及选择Flutter作为跨平台框架的原因,其次会介绍Flutter中与音视频关系非常大的外接纹理概念,以及对它做出的一些优化。之后会对闲鱼在音视频实践过程中碰到的一些Flutter问题提出了一些解决方案——TPM音视频框架。最后是闲鱼Flutter多媒体开源组件的介绍。

Flutter

Flutter是一个跨平台框架,以往的做法是将音频、视频和网络这些模块都下沉到C++层或者ARM层,在其上封装成一个音视频的SDK,供UI层的PC、iOS和Android调用。

而Flutter做为一个UI层的跨平台框架,顾名思义就是在UI层也实现了一个跨平台开发。可以预想的是未Flutter发展的好的话,会逐渐变为一个从底层到UI层的一个全链路的跨平台开发,技术人员分别负责SDK和UI层的开发。

在Flutter之前已经有很多跨平台UI解决方案,那为什么选择Flutter呢?

我们主要考虑性能和跨平台的能力。

以往的跨平台方案比如Weex,ReactNative,Cordova等等因为架构的原因无法满足性能要求,尤其是在音视频这种性能要求几乎苛刻的场景。

而诸如Xamarin等,虽然性能可以和原生App一致,但是大部分逻辑还是需要分平台实现。

我们可以看一下,为什么Flutter可以实现高性能:

原生的native组件渲染以IOS为例,苹果的UIKit通过调用平台自己的绘制框架QuaztCore来实现UI的绘制,图形绘制也是调用底层的API,比如OpenGL、Metal等。

而Flutter也是和原生API逻辑一致,也是通过调用底层的绘制框架层SKIA实现UI层。这样相当于Flutter他自己实现了一套UI框架,提供了一种性能超越原生API的跨平台可能性。

但是我们说一个框架最终性能怎样,其实取决于设计者和开发者。至于现在到底是一个什么状况:

在闲鱼的实践中,我们发现在正常的开发没有特意的去优化UI代码的情况下,在一些低端机上,Flutter界面的流畅性是比Native界面要好的。

虽然现在闲鱼某些场景下会有卡顿闪退等情况,但是这是一个新事物发展过程中的必然问题,我们相信未来性能肯定不会成为限制Flutter发展的瓶颈的。

在闲鱼实践Flutter的过程中,混合栈和音视频是其中比较难解决的两个问题,混合栈是指一个APP在Flutter过程中不可能一口气将所有业务全部重写为Flutter,所以这是一个逐步迭代的过程,这期间原生native界面与Flutter界面共存的状态就称之为混合栈。闲鱼在混合栈上也有一些比较好的输出,例如FlutterBoost。

外接纹理

在讲音视频之前需要简要介绍一下外接纹理的概念,我们将它称之为是Flutter和Frame之间的桥梁。

Flutter渲染一帧屏幕数据首先要做的是,GPU发出的VC信号在Flutter的UI线程,通过AOT编译的机器码结合当前Dart Runtime,生成Layer Tree UI树,Layer Tree上每一个叶子节点都代表了当前屏幕上所需要渲染的每一个元素,包含了这些元素渲染所需要的内容。将Layer Tree抛给GPU线程,在GPU线程内调用Skia去完成整个UI的渲染过程。Layer Tree中有PictureLayer和TextureLayer两个比较重要的节点。PictureLayer主要负责屏幕图片的渲染,Flutter内部实现了一套图片解码逻辑,在IO线程将图片读取或者从网络上拉取之后,通过解码能够在IO线程上加载出纹理,交给GPU线程将图片渲染到屏幕上。但是由于音视频场景下系统API太过繁多,业务场景过于复杂。Flutter没有一套逻辑去实现跨平台的音视频组件,所以说Flutter提出了一种让第三方开发者来实现音视频组件的方式,而这些音视频组件的视频渲染出口,就是TextureLayer。

在整个Layer Tree渲染的过程中,TextureLayer的数据纹理需要由外部第三方开发者来指定,可以把视频数据和播放器数据送到TextureLayer里,由Flutter将这些数据渲染出来。

TextureLayer渲染过程:首先判断Layer是否已经初始化,如果没有就创建一个Texture,然后将Texture Attach到一个SufaceTexture上。

这个SufaceTexture是音视频的native代码可以获取到的对象,通过这个对象创建的Suface,我们可以将视频数据、摄像头数据解码放到Suface中,然后Flutter端通过监听SufaceTexture的数据更新就可以顺利把刚才创建的数据更新到它的纹理中,然后再将纹理交给SKIA渲染到屏幕上。

然而我们如果需要用Flutter实现美颜,滤镜,人脸贴图等等功能,就需要将视频数据读取出来,更新到纹理中,再将GPU纹理经过美颜滤镜处理后生成一个处理后的纹理。按Flutter提供的现有能力,必须先将纹理中的数据从GPU读出到CPU中,生成Bitmap后再写入Surface中,这样在Flutter中才能顺利的更新到视频数据,这样做对系统性能的消耗很大。

通过对Flutter渲染过程分析,我们知道Flutter底层需要渲染的数据就是GPU纹理,而我们经过美颜滤镜处理完成以后的结果也是GPU纹理,如果可以将它直接交给Flutter渲染,那就可以避免GPU-CPU-GPU这样的无用循环。这样的方法是可行的,但是需要一个条件,就是OpenGL上下文共享。

OpenGL

在说上下文之前,得提到一个和上线文息息相关的概念:线程。

Flutter引擎启动后会启动四个线程:

第一个线程是UI线程,这是Flutter自己定义的UI线程,主要负责GPU发出的VSync信号时候用当前Dart编译的机器码和当前运行环境创建出Layer Tree。

还有就是IO线程和GPU线程。和大部分OpenGL处理解决方案中一样,Flutter也采取一个线程责资源加载,一部分负责资源渲染这种思路。

两个线程之间纹理共享有两种方式。一种是EGLImage(IOS是 CVOpenGLESTextureCache)。一种是OpenGL Share Context。Flutter通过Share Context来实现纹理共享,将IO线程的Context和GPU线程的Context进行Share,放到同一个Share Group下面,这样两个线程下资源是互相可见可以共享的。

Platform线程是主线程,Flutter中有一个很奇怪的设定,GPU线程和主线程共用一个Context。并且在主线程也有很多OpenGL 操作。

这样的设计会给音视频开发带来很多问题,后面会详细说。

音视频端美颜处理完成的OpenGL纹理能够让Flutter直接使用的条件就是Flutter的上下文需要和平台音视频相关的OpenGL上下文处在一个Share Group下面。

由于Flutter主线程的Context就是GPU的Context,所以在音视频端主线程中有一些OpenGL操作的话,很有可能使Flutter整个OpenGL被破坏掉。所以需要将所有的OpenGL操作都限制在子线程中。

通过上述这两个条件的处理,我们就可以在没有增加GPU消耗的前提下实现美颜和滤镜等等功能。

TPM

在经过demo验证之后,我们将这个方案应用到闲鱼音视频组件中,但改造过程中发现了一些问题。

上图是摄像头采集数据转换为纹理的一段代码,其中有两个操作:首先是切进程,将后面的OpenGL操作都切到cameraQueue中。然后是设置一次上下文。然后这种限制条件或者说是潜规则往往在开发过程中容易被忽略的。而这个条件一旦忽略后果就是出现一些莫名其妙的诡异问题极难排查。因此我们就希望能抽象出一套框架,由框架本身实现线程的切换、上下文和模块生命周期等的管理,开发者接入框架以后只需要安心实现自己的算法,而不需要关心这些潜规则还有其他一些重复的逻辑操作。

在引入Flutter之前闲鱼的音视频架构与大部分音视频逻辑一样采用分层架构:

1:底层是一些独立模块

2:SDK层是对底层模块的封装

3:最上层是UI层。

引入Flutter之后,通过分析各个模块的使用场景,我们可以得出一个假设或者说是抽象:音视频应用在终端上可以归纳为视频帧解码之后视频数据帧在各个模块之间流动的过程,基于这种假设去做Flutter音视频框架的抽象。

咸鱼Flutter多媒体开源组件

整个Flutter音视频框架抽象分为管线和数据的抽象、模块的抽象、线程统一管理和上下文同一管理四部分。

管线,其实就是视频帧流动的管道。数据,音视频中涉及到的数据包括纹理、Bit Map以及时间戳等。结合现有的应用场景我们定义了管线流通数据以Texture为主数据,同时可以选择性的添加Bit Map等作为辅助数据。这样的数据定义方式,避免重复的创建和销毁纹理带来的性能开销以及多线程访问纹理带来的一些问题。也满足一些特殊模块对特殊数据的需求。同时也设计了纹理池来管理管线中的纹理数据。

模块:如果把管线和数据比喻成血管和血液,那框架音视频的场景就可以比喻成器官,我们根据模块所在管线的位置抽象出采集、处理和输出三个基类。这三个基类里实现了刚才说的线程切换,上下文切换,格式转换等等共同逻辑,各个功能模块通过集成自这些基类,可以避免很多重复劳动。

线程:每一个模块初始化的时候,初始化函数就会去线程管理的模块去获取自己的线程,线程管理模块可以决定给初始化函数分配新的线程或者已经分配过其他模块的线程。

这样有三个好处:

一是可以根据需要去决定一个线程可以挂载多少模块,做到线程间的负载均衡。第二,多线程并发式能够保证模块内的OpenGL操作是在当前线程内而不会跑到主线程去,彻底避免Flutter的OpenGL 环境被破坏。第三,多线程并行可以充分利用CPU多核架构,提升处理速度。

从Flutter端修改Flutter引擎将Context取出后,根据Context创建上下文的统一管理模块,每一个模块在初始化的时候会获取它的线程,获取之后会调用上下文管理模块获取自己的上下文。这样可以保证每一个模块的上下文都是与Flutter的上下文进行Share的,每个模块之间资源都是共享可见的,Flutter和音视频native之间也是互相共享可见的。

基于上述框架如果要实现一个简单的场景,比如画面实时预览和滤镜处理功能,

1:需要选择功能模块,功能模块包括摄像头模块、滤镜处理模块和Flutter画面渲染模块,

2:需要配置模块参数,比如采集分辨率、滤镜参数和前后摄像头设置等,

3:在创建视频管线后使用已配置的参数创建模块

4:最后管线搭载模块,开启管线就可以实现这样简单的功能。

上图为整个功能实现的代码和结构图。

结合上述音视频框架,闲鱼实现了Flutter多媒体开源组件。

组要包含四个基本组件分别是:

1:视频图像拍摄组件

2:播放器组件

3:视频图像编辑组件

4:相册选择组件

现在这些组件正在走内部开源流程。预计9月份,相册和播放器会实现开源。

后续展望和规划

1:实现开头所说的从底层SDK到UI的全链路的跨端开发。目前底层框架层和模块层都是各个平台各自实现,反而是Flutter的UI端进行了跨平台的统一,所以后续会将底层也按照音视频常用做法把逻辑下沉到C++层,尽可能的实现全链路跨平台。

2:第二部分内容为开源共建,闲鱼开源的内容不仅包括拍摄、编辑组件,还包括了很多底层模块,希望有开发者在基于Flutter开发音视频应用时可以充分利用闲鱼开源出的音视频模块能力,搭建APP框架,开发者只要去负责实现特殊需求模块就可以,尽可能的减少重复劳动。

Flutter入门这一篇效率文章就够了

本文面向 Flutter 初学者,旨在用易懂的方式带大家入门。除了 Flutter 代码,还会介绍到语法、原理、特性等基础知识。相信本文能帮助你学习和理解 Flutter。

我们先看一下目前的一些跨平台方案,从前端渲染的角度来分类的话,大致可以分为以下几种方案。

WebView 渲染

这种方案就很好理解,现在很多项目都会嵌入 H5 的页面。就是用 JavaScript 等前端技术进行开发,在客户端上用 WebView 来进行渲染。微信小程序目前使用的就是这种方案。

它的优点很明显,使用成熟的前端技术进行开发,学习成本低,开发效率高,并且支持动态发布代码。

但缺点也很明显,在性能体验上,和原生还是存在较大差距的。

原生控件渲染

既然 WebView 的性能不够好,于是就有了使用原生控件进行渲染的方案。这种方案,同样也是使用 JavaScript 开发,区别是它最终是调用原生控件进行渲染的。这种方案的代表是 Facebook 的 React Native。

由于使用原生控件进行渲染,性能体验也会更接近原生。但也只是更接近,和原生还是有差距的,因为它需要频繁的进行 JavaScript 和原生之间的通信,这个通信效率是比较低的。

另外,由于需要适配各个平台的控件,那就有可能出现,系统控件更新了,而框架本身还没有更新,由此产生了一些问题。换句话说,这种方案是受到原生控件限制的。

绘图引擎渲染

接下来就是主角了。

在前端,如果完全不使用原生控件,我们可以通过系统的绘图 API 绘制出一个用户界面。从这个角度出发,可以在各个平台使用一个统一接口的绘图引擎来进行界面绘制,这个引擎最终调用的是系统的 API 绘制的。这样的话,它的性能可以做到接近原生,并且又不受原生控件的限制,在不同平台上能够做到 UI 统一。

Flutter 就是这样的一个开发框架。

一个跨平台 UI 解决方案

Flutter 是由 Google 开发的,一个跨平台 UI 解决方案。换句话说,它原则上只管 UI 的问题,如果涉及到平台本身的一些功能,比如调用蓝牙、摄像头,一般还是需要原生代码去操作。但现在也会有一些第三方库帮我们解决这些问题。

绘图引擎 Skia

Flutter 使用 Skia 作为它的绘图引擎。Skia 已经被 Google 收购,目前很多 Google 旗下的产品都是用 Skia 绘制的,包括 Android。

Android 内置了 Skia,但 iOS 没有,所以在打 iOS 安装包的时候,会把 Skia 一起打进去。这就导致了,用同一份 Flutter 代码打包之后,iOS 的包要比 Android 的包大一些。

开发语言 Dart

Flutter 使用的开发语言,叫 Dart。Dart 也是 Google 自家的,它是一门面向对象的语言,从它身上会看到一些其他开发语言的影子。学习起来难度不大的。

前面讲跨平台方案的时候,可以发现别的方案基本都是用 JavaScript 作为开发语言的,但为什么 Flutter 不用?就因为 Dart 是谷歌自家的吗?这个问题先留着,我们后面会提到。

这里部分就简单点带过了,具体的搭建流程可以在官网查看:

主要的搭建步骤如下:

下载 Flutter SDK

官网下载地址:

由于在国内访问可能受限,官方为中国开发者搭建了镜像:

更新环境变量

解压后,将 flutter\bin 的全路径添加到环境变量 PATH 中。

安装开发工具

理论上,任何文本编辑器都可以用来开发 Flutter 应用,但推荐的开发工具是 Android Studio、IntelliJ 以及 VS Code。因为在这些开发工具上,可以安装官方的 Flutter 和 Dart 插件,得到更好的开发体验。文章里使用 Android Studio 来演示。

如果你打算开发 iOS 应用,则还需要安装 Xcode。

安装插件

在开发工具的插件设置中,安装上面说到的 Flutter 和 Dart 插件。Flutter 插件用于支持 Flutter 的运行、调试、热重载等功能,而 Dart 插件则提供了代码的输入校验、代码补全等功能。

万物始于 Hello World,我们先来创建一个显示 Hello World 的 Flutter 项目。

在 Android Studio 的欢迎页面选择 Start a new Flutter project ,或者通过菜单栏的 File New New Flutter Project ,创建一个新的 Flutter 项目。

创建好的项目里面包含了 android 和 ios 两个文件夹,它们是标准的 Android 和 iOS 项目。我们的 Flutter 代码,存放在 lib 文件夹里。项目创建好后,会默认带一个计数器的示例,我们不管它,把 main.dart 的代码改成 Hello World:

启动一个模拟器,或者连上真机,点击 Run 运行一下,就能看这样一个界面了:

具体代码先混个眼熟就好,具体的后面会再讲到。

在写 Flutter 之前,还要先跟大家简单介绍一下 Dart 的语法。如果你有 Java 或 JavaScript 的开发经验,以及面向对象的编程思想,学起来是很快的。

我们可以在 test 文件夹下新建一个 dart 文件,用来写测试代码。

指定类型

var

但和 JavaScript 不同的是,以下代码在 JavaScript 是不会报错的,但在 Dart 里会报错:

Object

如果非要上面这样写,那也可以。把 var 换成 Object 就不报错了:

和 Java 类似,Object 是所有对象的根基类。但是这样的话,如果想打印一下 num 的字符串长度,是会报错的:

因为 length 是属于 String 的,但系统只知道 num 是一个对象,并不知道它是一个 String。

dynamic

如果还是非要这样写,那也可以。Dart 有一个特有的关键字 dynamic,把 Object 改成 dynamic 就不报错了:

我们运行一下这个文件,可以在控制台看到正确打印出了字符串长度。

函数

dynamic

在 Dart 里,函数也是可以不写返回类型的,不写的话会被当做 dynamic 来处理。这样的话,函数的类型就是 return 的类型,如果没有 return 则是 void 类型。比如可以这样:

运行之后是能正确打印出字符串长度的。

用于传参

Dart 里的函数也是一个对象,所以可以把函数作为参数来传递,比如:

可选参数

在 Dart 的函数传参里,有一个叫可选参数的概念,我们以文字控件 Text 为例,在源码里可以看到 Text 的构造函数是这样的:

首先,在参数里有一个 data,它是要显示的文字内容,是一个必填项。而 data 后面的一堆参数,是用一个大括号括起来的,这些参数就叫做可选参数,意思是这些参数可传可不传。

假如我们要显示一个比较长的文字,又想限制它最多显示两行,就可以这样来创建一个 Text:

可选参数,在 Flutter 里面用的非常多。

异步

Future

在 Dart 里使用 Future 来处理异步任务,比如我们现在延时一秒打印 666,代码如下:

Future 的语法和 Promise 非常像。任务执行成功会调用 then,执行失败会调用 catchError,而无论成功还是失败,都会调用 whenComplete。

async/await

如果你不喜欢上面那种写法,或者是想把异步转成同步,就可以用 async 和 await 这两个关键字来转换。

我们把上面的代码转换一下,写一个 getString 方法,返回的类型是 Future,它会延时返回一个字符串。在 main 函数后面加上 async 关键字,在 getString() 前面加上 await,代码如下:

运行之后可以看到,能正常延时一秒后,把字符串打印出来。这里 getString() 返回的类型是 Future,而 await getString() 则是返回了延时之后返回的字符串。await 要在 async 的函数里面才能使用。

async 和 await 其实是一个语法糖,它最终也是转换成 Future 调用链的形式执行的。

接下来回到 Flutter,Flutter 里最重要的一个概念是 Widget(下面翻译作控件)。

在原生开发里面,我们可能会在界面上区分,这是一个 View,这是一个 Layout,这是一个 View Controller。但在 Flutter 里面,它们全都属于一个统一的模型 Widget。可以说,在 Flutter 界面里,所有东西都是 Widget。

以前学面向对象的时候,我们都听过一句话,叫万物皆对象。我这里套用一下,在 Flutter 里, 万物皆控件 。

具体有哪些控件,我做了一下简单的分类。

根控件

所有的控件都属于 StatefulWidget 或 StatelessWidget 。它们的区别是,StatefulWidget 拥有状态 State ,而 StatelessWidget 没有。

StatefulWidget

当一个控件是可变的时候,就要使用 StatefulWidget 来构建。StatefulWidget 本身不可变,但它持有的状态 State 是可变的。

StatelessWidget

当一个控件状态是固定不可变的时候,就可以使用 StatelessWidget。前面我们写的 Hello World 就是使用 StatelessWidget。

容器控件

容器类控件一般是将某些属性或配置,作用在它的子控件上,比如控件所在的宽高、背景、位置等。

常用的容器控件有 Container、Center、Padding 等。

布局控件

布局控件可以类比作原生开发中的 Layout,通常它会拥有一个 children 的属性,用于接收一个控件数组,对这些控件进行特定的排版。

常用的布局控件有 Row、Column、Stack、Flex 等。

基础控件

基础控件就是常用的文字、按钮、图片等控件。

常用的基础控件有 Text、TextField、Button、Image 等。

功能控件

在 Flutter 里还有一类控件,它们不影响 UI 布局,但带有一些特定的功能,比如页面跳转、事件监听、定义主题等。我们把这一类控件称作功能控件。

常用的功能控件有 Navigator、NotificationListener、Theme 等。

开始写 Flutter 代码了。还记不记得,在 Flutter 项目创建之后,是自带一个计数器 demo 的,现在我们用自己的代码实现一遍。代码修改成如下:

运行之后,就可以看到这样的界面了:

按钮每点击一次,数字就会加一。下面我们来分析一下这段代码,看下里面用到的一些 Widget。

StatefulWidget

由于页面中的数字是跟随状态变化的,所以该页面改用 StatefulWidget。StatefulWidget 并不会直接返回一个 Widget,而是返回状态 State,在 State 里再返回 Widget。

Scaffold

Scaffold 是一个标准的 Material Design 页面,它包含了标题栏、浮动按钮、侧滑菜单、底部导航栏等配置。我们这里用到了标题栏 appBar、页面内容 body、浮动按钮 floatingActionButton。

AppBar

AppBar 就是标题栏,通过查看控件的构造方法,我们可以知道它可配置的属性。

AppBar 的可选参数除了标题 title,还可以配置标题前的内容 leading,右侧的操作按钮 anctions,控件垂直高度 elevation 等。我们只传了 title,其他属性都用默认值。

Center

Center 是一个容器类控件,它的作用就是让它的子控件居中显示。

FloatingActionButton

熟悉安卓开发的应该对这个控件比较熟悉,它就是页面右下角一个特定样式的 Button,参数里面的 onPressed 是一个必填项,要传一个点击之后的回调函数。

根据这个例子,下面给大家介绍一下 Flutter 两个比较重要的特性。

点击 Button 之后,我们把 num 变量加一,并使用 setState 通知状态发生了改变,Flutter 会根据新的状态更新 UI。如果有接触过小程序开发,setState 就和小程序的 setData 类似。

在 Flutter 里面我们不需要用 set 方法来更新 UI,可变控件是和状态绑定的,这就是 Flutter 的响应式 UI 编程。

在 Android Q 和 iOS 13 里都加入了暗黑模式,我们也换一个暗黑主题来玩一下。MaterialApp 里有一个 theme 的属性,我们把它配置一下:

这次改完之后不点 Run 了,我们点一下闪电图标 Flutter Hot Reload ,就能看到界面发生了变化:

这就是 Flutter 的 热重载 ,在修改完代码之后,通过热重载就能马上在设备上看到修改结果,可以很大程度上增加开发效率。

下面再给大家介绍几个 Flutter 里的常见操作。

在 Flutter 里,使用 Navigator 来管理页面跳转,比如要跳转到一个 NewPage 可以这样写:

进栈使用 push,出栈则是 pop。

使用 MaterialPageRoute 会模拟出 Android 上页面跳转的过场效果。

我们来看看怎么显示一张本地图片。

先在根目录新建一个存放图片的文件夹,比如叫 images,把图片 picture.png 放进去。

找到根目录下的 pubspec.yaml 文件,这个便是 Flutter 依赖配置文件,我们需要在这里配置一下刚才的图片:

这样,我们就能使用 Image 控件把这张图片显示出来了:

和 node 的 npm 以及 Android 的 jcenter 类似,Flutter 也拥有一个公共仓库 pub.dev。pub.dev 是 Google 官方的 Dart 仓库,在上面可以找到我们需要的包和插件。

Flutter 本身没有 Toast,我们来接入一个。在 pub.dev 上搜索后,我决定使用 fluttertoast:

按照说明,在 pubspec.yaml 文件里的 dependencies 下配置:

点一下 Android Studio 右上角的 Packages get 同步之后就可以使用了:

我们上面使用的都是 Material Design 的控件,它们都是在 flutter/material.dart 包里面的。如果要使用 iOS 风格的控件,则要用到 flutter/cupertino.dart 包:

iOS 风格的控件,基本都以 Cupertino 开头。我们把计时器页面里的控件替换一下:

效果如下:

代码的部分就到这里了,接下来跟大家聊一下编译方式,编程语言的编译方式有两种。

关于它们孰优孰劣,就要看从哪个角度去对比了。JIT 的话,它的一大特点就是支持动态发布代码,也就是支持热更新。但要是从性能的角度考虑,AOT 会更好,因为在运行的时候不用再进行编译的操作的,运行的效率会更高一些。

回到我们一开始的时候留下的问题,为什么别的跨平台方案都是用 JavaScript,而 Flutter 要用 Dart 来开发。JavaScript 的编译方式是 JIT 的,它不支持 AOT。而 Dart 同时支持 JIT 和 AOT。

Flutter 在开发阶段使用 JIT,让我们用上了热重载,增加了开发效率。在打包时改用 AOT,保证了正式版应用的性能。

最后讲一下大家比较关心的一个东西,Flutter 是否支持热更新?前面说到 Dart 支持 JIT,所以从技术层面它是支持的。但是目前是不支持的,在官方的计划文档中,可以看到:

至于原因,官方在这里进行了说明。总的来说,是由于政策的限制,以及出于对性能和安全性的考虑,暂时不支持了。

到这就结束啦。由于想把 Flutter 基础在一篇内讲完,没有涉及太多细节,如果要写 Flutter 代码还需要深入学习。但相信理解之后再学,会轻松很多。

离不开DART的Flutter(dart篇)

hello world例子

在终端打印字符串‘Hello World!’

计算斐波那契数列

一个简单的类

计算两点距离

异步并发示例

使用了Isolate

1.面向对象

对于面向对象这个概念,相信了解Java的同学对这个概念一定不会陌生。

例如:我们有个Person Object他有很多特征和行为。

这些都是这个Person Object的属性。

也就是因为有了这些特征,行为等等才决定了这个人是谁。

那么回到Dart当中,所有的都是对象,那么在就可以可以跟进对象的属性的特征,方法等等来进行编程。

之所以我们在这里又特别强调了一下面向对象的概念,是因为这个概念在Dart语言当中,至关重要!

2.最重要的几个概念

3.Dart的部分特性

4.Dart的内置库

包名

描述

dart:asynv

异步编程,提供Future,Stream类

dart:collection

集合

dart:convert

不同类型的字符编码解码

dart:core

Dart语言核心功能,内置类型

dart:html

网页开发用到的库

dart:io

文件读写,IO相关

dart:math

数字常量以及函数,随机算法等

dart:svg

事件和动画矢量图支持

综上述所说要想学Flutter,先学Dart!关于Flutter下篇我会讲到。为什么离不开dart!

有关更多面经、核心技术笔记;自己也是从事Android开发5年有余了;整理了一些Android开发技术核心笔记和面经题纲, 如有需要的同学请私信我回复“核心笔记”或“面试”领取!

app是如何制作的,APP如何开发?

手机APP制作流程:无需技术,教你制作一个自己的手机APP

一款手机APP的制作,说复杂非常复杂,涉及到多个领域的研发,稍复杂一点的个人研发基本上搞不定,但是,也有非常简单的手机APP一站式制作运营方法。

随着移动互联网基层开开发技术的发展,无需编程技术,也可以在应用公园制作手机。这里就以应用公园为例,教您熟悉手机APP制作流程,手把手教你制作一款自己心仪的手机APP。

第一步:了解自己想要制作一款怎么的手机APP。是软硬件结合? 游戏 类?商城类?新闻资讯类?互动类?聊天类?还是团购类、同城服务类?送餐类?企业展示类?

每一个类别的APP开发差异非常大,主要就是不同类型所需要的功能支持。对自己想要做的APP有个大致的了解,但是这一步很多人都没搞清楚,大部分人都存在一个大概模糊的创意、想法阶段。

第二步:了解自己想要做的APP的基础功能,划分板块。

对基础功能的了解、板块的分类,上手最快的方法就是:查看市场上类似的APP进行借鉴。

第三步:界面及交互的设计

界面及交互的设计,可以直接使用“墨刀”。可以先设计一个大概,后期不断丰富。

第四步:APP功能的开发制作

APP功能的开发直接使用应用公园就可以了。应用公园把市场上常见的APP功能进行拆分组合,你不需要懂任何编程技术,只需哟安把需要的功能挑选出,组合搭配一个,就能迅速组建出一个手机APP。

手机APP制作具体流程:

1、打开应用公园的官网,点击“开始制作”,注册登录;

2、应用公园为在线APP制作平台,所以不需要下载任何东西,直接进入制作页面就可以;

3、应用公园目前有两种模式:

(1)主题模式:应用公园平台上,已经很多已经制作完善的手机APP软件,可以直接当做模板使用,仅需要把里面的文字图片进行替换,就可以快速制作一款APP。

(2)自由模式:就像拼图一样,把需要的功能自由组合搭配一下,就可以创造一款独一无二的手机APP。

每一个功能控件的具体功能,都通过后台自动配置。

4、手机APP打包

制作完善后,在应用公园平台直接点击制作完成,就会自动打包成手机安装程序。

5、应用发布上架

在应用公园平台直接申请应用发布,通过联网后,就可以联网使用了。

6、下载管理、运营

应用公园提供运营管理后台、下载站点、下载二维码、手机管理助手等APP相关产品,一站式服务,自动配置,免去多次开发成本,而且后期的功能、内容的更新迭代自己既可以搞定,也不需要具体的编程技术。

自己制作app需要 编程知识 。但依靠第三方工具,三分钟就可以做成专属自己的APP。下面以简易网为例演示:

简网APP工厂三大特点

1、最低的成本:节省所有开发成本,以及仅几分钟的时间成本。

2、实用的功能:贴近传统网站的内容编辑与发布方式。

3、灵活的运营:生成APP后,一个人也可以完美运营。

先来了解一下APP工厂:三分钟制作APP

使用简网APP工厂之前,我曾经通过其他类似的APP公司制作过两三个不同版本的免费APP,简网的操作流程是制作门槛最低的一家。

不支持用户名注册,需要使用微博账号

新浪与腾讯微博用户数几乎覆盖全网网民数,我们默认用户已经拥有微博账号,以便于进行APP快速创建。

填写APP信息:几分钟搞定

制作APP之前我们需要做一些准备工作,比如我们要明确我们要做一个怎样的APP,我们要为这个APP准备一张1024x1024的ICON以及一张114x114的小图标,另外还需要一张640x1136的开机图。

从简网APP工厂的首页,经过3次跳转,省略了网站注册过程,通过模板挑选完成APP美工定案,所需的是APP的图标与应用简介。全过程几分钟足矣。

快捷实用的后台采编系统

我们制作了一个新闻资讯类的APP软件,同时我们拥有了一个功能齐全的后台更新系统。利用后台可以完全解决APP内容更新问题,可以快速进行新闻发布,包括文字、图片、视频、微博等形式,并且引入了完善的评论系统与社区系统。

笔者至今使用过三家大型网站的后台系统,由于种种 历史 原因,这些后台系统都存在或多或少的不合理设计,也许是因为承载的功能过多,数据架构过于复杂,在新入职人员上手操作时,需要经过长时间的熟悉过程。

简网为我们制作的APP提供了统一的后台模板,这个后台的功能亮点在于不仅提供原始录入,还提供也许是目前设计最为合理的网络来源抓取功能。包括网页、微博在内的网络内容,都可以在大约1分钟时间内导入后台中,并且实时呈现在用户手机上的APP客户端。

APP的生成时间约为三分钟,APP容量只有3M,一般的宽带都可以在1分钟之内下载好装进手机

我们得到了一个可安装的APP软件

同时获得了一个功能完善的编辑后台

快速的内容抓取,让后台采编人员的数量可以降到最低,维持一个日更新量在100篇文章左右的APP客户端,一个工作人员足矣。

内容采编神器:发布到应用

“发布到应用”这个功能可以说是管理后台提供的最强大的一个功能,经过简单的设置后,我们可以在几秒钟之内把网络内容发布到我们的APP客户端。

这样一个媒体类APP就做好了。

很高兴回答这个问题。

我是从事安卓App开发的,开发过很多App,那么App是如何制作的。

页面设计

我们看到的app都一个个页面,每个页面功能不同。首先是产品经理通过调研整理需求,然后将需求整理成页面(可以使用墨刀等网页制作),然后在交给UI人员进行专业设计和美化,最后将设计图打包给开发人员。

开发设计

拿安卓举例,开发使用语言也分几种,具体得根据实际情况来选择。

1.原生开发

安卓一般使用java语言开发,当然现在也有kotlin语言进行开发。如何开发就涉及到具体编程了,这里就不详说了。简单描述就是使用安卓提供的一系列控件来实现页面,复杂点的页面可以通过自定义控件来实现。

2.使用H5语言开发

使用H5开发的好处有很多,可以多端复用,比如浏览器端,ios端,当然H5开发的体验是没有原生好的。结合我做过的项目来说,一般是这个页面需要分享出去的话,就用H5开发。

3.使用flutter开发

flutter是近年来谷歌推出的一款UI框架,

使用dart语言进行开发,支持跨平台,weight渲染直接操作硬件层,体验可媲美原生。但是flutter技术比较新,生态还不完善,开发起来效率相对偏低

页面数据填充

页面开发出来只是空壳子,没有数据填充,这时候就需要通过接口获取数据,然后解析数据,显示在页面上。

到此,一个大概的App制作流程就结束了。

首先你要清楚自己想要什么样的APP,是做哪一方便的?简单的?还是复杂的

一下我就分为两类进行回答

一,简单APP

必要岗位

ui设计师(至少一个)

主要负责APP页面的搭建和交互的梳理

客户端开发人员(至少一个)

目前市面上的APP开发方式多为混合开发,如果做一个简单的APP可以选择webapp,这样不但可以减少开发周期还可以控制开发成本

服务端开发(至少一个)

目前服务器语言很多php,java,

node.js

非必要岗位

首先 ,我说的非必要岗位不是说这些岗位不重要,而是说在为了减少成本的情况下,这样岗位可以被别的岗位所替代

产品经理

如果开发的App功能简单,UI设计师就可以担任这样职责

测试工程师

当然,在时间允许的情况下,开发人员也可以是测试人员

二,复杂APP

复杂app可以考虑纯原生开发,那么客户端至少两个人进行开发(安卓,IOS),或者考虑混合开发,及web前端+原生开发人员

必要岗位

ui设计师,安卓开发工程师,ios开发工程师,后端开发工程师,产品经理,测试工程师,人员的多少可以根据项目的大小来定

三,必要成本

服务器 :这是开发app必须要的,也就是我们放代码的地方

上架审核所需费用 :比如IOS上架审核的花好几百,安卓要申请软著等

今年六月的时候,萌生了开发一个记账 App 的想法,想去用自己的 App 记账,管理收支。那时正好在英国是考试周,放假后,我回到了国内,准备去实现我的计划。没想到这暑假很快就结束了,在这个暑假中经历的太多的事,准备了要去美国读研的考试,遇到了生命中的另一半,同时,也将 Costuary for iPhone 带到了这个世界。

Logo

说道为什么要开发这样一个 App ,因为笔者在 UK 读书,市面上很少有记账 App 能够实现实时汇率的换算,带有这个功能的 App 也是操作繁杂。所以要自己开发一个,功能并没有那么复杂的,并且能够满足自己在国外和国内生活需求的 App,所以自己编写了 iPhone 的客户端,为了获取汇率和 Excel 导出,又用 Java 设计和编写了 Costuary 的后端服务器。

比起今年年初开发的 Flat Weather,这个项目的代码量大约是他的十倍,需要实现众多的功能和模块。

这篇文章将会介绍一下 Costuary 的功能与我开发过程中的一些心得。

效果图设计

说到设计,两年前,我还是一个 Android 开发者,Google 的 Material Design 是我的最爱,所以,Costuary 采用了 Android 5.0 之后采用的 Material Design 设计。其中掺杂了一些我自己的设计,因为 Material Design 的控件有时候操作繁琐。

早在 5 月份的时候已经零零总总的用 Sketch 画出了这个产品的 UI 和图标,之后开始了漫长开发的过程。

Sketch交互

与去年开发的 Android 版不同,iPhone 版的 Costuary 采用了底部导航栏的设计,相比于 Android 通常使用的 Navigation Drawer 的抽屉布局,底部导航栏的设计即使在右手操作 iPhone 的时候都不会太费力。

UX功能 Features

Costuary 支持世界上主要货币的实时汇率转换,所有外汇在统计时会转换成主货币的数目,方便查看花销。

日历视图能够很直观的反映出哪一天有消费和收入。

说到记账软件,量化消费的图表无疑是重要的一环,Costuary 提供了饼状图来视觉化一段时间的花销。

可以建立多个账户来表示自己的银行卡,支付宝,现金等等。

可以看出本月的预算还有多少。

如果想要进行更加详细的分析,可以使用导出功能将账本导出到 Excel。

允许备份账本内容到 iCloud。

开发

去把一纸设计变成真正的产品,这是一个独立开发者应该具有的能力。只会写代码不只是我唯一掌握的,能够去设计出来自己想要的应用并且将他实现才是我在做的事情。

这款应用的开发并没有想象中的简单,需要自己去实现大量 Android UI 控件,很多圆角,阴影,字体,要慢慢的去调整,让控件适合 iPhone 的屏幕。整个应用的背后有 3 个关系型数据库来储存账户,账本与各种汇率。与以前开发的 Flat Weather 不同,Costuary 会产生大量的用户数据,所以整个软件架构的稳定性变得异常重要,需要设计一些机制来防止数据丢失与损坏。

Development

为了实现 App 获取每日的汇率,并且在 iPhone 上能够实现账本导出到 Excel ,我设计了一个服务器后端来处理这些繁杂的实物。每次 App 启动后会与我的服务器来更新最新的汇率。当用户选择导出时,账本会被发送到服务器上并处理为 Excel 发送到用户的邮箱里。

Mail

说到服务器,就不得不提到用户隐私了,因为导出到 Excel 功能需要将账本传到我的服务器上做进一步处理,很多人会觉得我侵犯了他的个人隐私。对此,为了保护我的权益与用户的权益,我撰写了 Costuary 软件许可及服务协议与 Costuary 隐私政策,这是我作为独立开发者这么多年后第一次去写许可协议。

Agreement资费

与我的其他产品一样,这款 App 依旧是免费供大家使用的,作为独立开发者,我们都知道,绝大多数用户不会去珍惜一个免费的产品。就像 Flat Weather 一样,虽然获得了很多人的支持,但是也收到了很多人的吐槽。在 Costuary 中依然设计了一个的捐助按钮,如果大家使用之后喜欢这个应用,请支持我将他维护下去。

Please donate me尾巴

Costuary for iPhone 是我开发出来过最大的软件体系。我相信,能够独立开发出来产品的人懂得不只是编程。一个人要去经历项目的全部生命周期:规划,设计,开发,运营,维护,营销,这些是我开发这么多产品所学会的。

现在的 Costuary 只是第一个版本,还有很多 iPhone 的特性没有来得及开发,以后会跟上的,比如 iPhone X 的适配,3D Touch、Today Widget、Touch ID 等等。

以前在少数派撰稿的时候,很多读者会来问我如何学习开发,我也特地去写过如何去学习编程,但我相信,真正想去学习的,想去为这个生态贡献出自己的一份力的人,自己都会找到学习的方法。我的专业是电子电器而不是软件工程,但是我不后悔当年去学习编程。

最后,还是感谢在背后默默支持我的人,我会不断地改进与提升,如果 Costuary 真的在记账方面给予了你便利,这是我莫大的荣幸。

如果想要了解我的更多作品可以访问我的个人博客 MikeTech,或者在少数派中阅读我以前写过的文章。今年年初也在 iPhone 上写过一个天气 App,天气应用 Flat Weather 的设计历程

对了,关于记账有什么用,如何记账,如何养成记账的习惯。为什么每个月末都捉襟见肘,除了没钱,很可能是对财务管理的能力不强。想了解这一方面的知识,不妨看一看我派的付费阅读栏目:从零开始做好个人记账

你好,非常感谢你的邀请。

开发一个app的话首先

第一步、需要调研,分析开发需求。

第二步、根据你的开发需求整理一个开发方案,选择合理的架构。

第三步、开始研发。

第四步、测试。

第五步、上线试运行。

第六步、查缺补漏后投入使用。

开发一个app的话。有多种选择。可以找一个第三方公司来进行开发。也可以自己招聘开发团队。也可以交给比较信任的程序员朋友来进行开发。第三种方式的话,属于接私活儿,成本较低。 当然前提你得有认识的人。

我也是程序员出身。参与过web网站开发。传统办公开发。H5开发。微信小程序开发。以及安卓开发。有着较丰富的开发经验。自己完全可以胜任一个App,如果你有这方面的事需求的话,也可以私信我。我是山东的。如果方便的话也可以面谈。

App软件开发,从之前的沟通需求、规划设计、程序开发、测试修改、它的发布等。这是一个非常复杂和漫长的过程,一旦进入通信,就需要定期维护和功能变更。它需要大量的专业人员参与,成本自然很高。 所以,随着更新市场的发展和人们福利的提高,现在已经不像传统开发那么困难了。只需要动动鼠标,不需要触碰代码就可以完成制作app部分。

App开发已成为企业发展的重要推动力量

十年巨变!移动互联网已颠覆我们的时代,商业、社交、视频、新闻、工具等领域,移动应用的渗透率已高达95%,在团购 旅游 和零售行业,移动端收入规模已超过PC端,手机APP已成为企业不可或缺的线上阵地。

不用编程就能制作app的在线平台,摆脱了很多复杂的流程,还能减少用户的麻烦,不会制作,而且可以在平台上查看详细的课程,非常贴心的设置!在这里,我想说的是,如果你想制作app的话,可以在平台上查看详细的课程。总的来说,这种方法会大大降低软件开发app的成本,节省时间,让很多人解决了资金短缺和想快速制作app的问题。

app是如何制作的,APP如何开发?

随着智能手机APP软件的吸引力越来越大,越来越多的企业开始开发自己的APP应用。企业要想开发属于自己企业的APP应用,首先要分析自身的情况和市场对产品的需求。

在APP,开发这件事上,企业一定要注意以下几点。

1. 开发APP应用一定要明确以自己为中心,开发APP是否能带来巨大的利润。

2. 要了解目标用户的需求,配置APP吸引用户,提高用户购买应用的意愿。

3. 通过合作再次寻找潜在客户,我相信开发APP的收益远远大于成本。

开发APP苹果系统,必须使用Xcode苹果开发工具,一般采用Objective-C或Swift语言。Objective-C是继承了C语言的C字,可以直接用Objective-C语言进行编程。如果你不懂数据,差别很小。还有一些新的苹果后缀语言,非常有用。

Andro系统的app都是用Java语言开发的,Java语言已经流行了20多年,这个趋势还在持续和延续。如果想要安卓系统的app首先要掌握Java语言,对于说C语言的人来说,学习Java还是很容易的。如果你对自学感兴趣,Java网站上有很多培训课程,还有很多免费培训。视频,不想付费。如果这个绝对是零基础(没学过其他编程语言,比如c语言),如果真的很感兴趣,可以自学,但是速度比较慢。

总结:app开发拥有多种方法,选择最适合自己的方式方法很重要

答案写到这里,我想您应该知道了app的开发途径或者方法是什么。如果您是小企业或者是个体工商户,您可以找人帮忙开发小程序或者自己在一些网站上进行傻瓜式软件开发。正如上文所说,现在有很多的网站支持在线生成APP,常用的功能和接口都已经设置好了,操作起来不是很难。如果您是大企业,业务多访问量比较大,我的建议是您应该聘请专业的软件工程师开发专门的app,避免后期出现的问题没办法及时解决给您的企业带来损失。

不懂的话,找专业的人帮忙,我就是专业的

app即application program。应用程序。目前手机平台是ios和安卓两大平台的天下。本人不才从事安卓开发。简单介绍一下吧你问的这个问题范围太广。ios和安卓开发语言不同。ios使用的是object_c和swift。安卓是基于java。二者都属于面向对象的语言。开发平台安卓基于android studio早期使用的是eclipse+adt。不过已经被淘汰了。那么怎样开发app?首先你需要一个后台程序员写服务器以及搭建数据库。其次你的会ios或是android其中之一那么这就是最简单的配置.现在流行混合开发如果你再会点前端的h5和js就更好了。一般一个软件公司的基本配置是一个前端一个ios一个安卓一个后台。基本就满足你搭建网站和手机应用的需求了。不过你作为老板养这样一个团队很费钱。还不如找外包

软件的生成需要经历以下几个阶段:

1、满足用户需求——建立软件目标,设想产品功能,进行场景化细分说明;进行可行性分析,用户需求收集,用户需求场景描述;场景问题梳理;获取用户行为、想法;场景应用痛点,机会点

2、需求开发与管理——建立用户画像,从软件目标出发,进行问题梳理,场景行为分析,愿景分析,建立体验地图

3、利用Axure绘制软件原型,在用户场景中切入,并组织软件原型实施,在实施过程中进行问卷调查,收集问题,记录用户行为,不断改善软件需求,进行需求评审,进入评审优化

4、技术可行性分析——技术分析,场景分析,功能实现验证,

5、开发计划制定,实施,测试,验证,发布

Flutter中InheritedWidget的使用

在Tree中从上往下高效传递数据的基类widget , 定义为:abstract class InheritedWidget extends ProxyWidget

Flutter的响应式开发与React类似,数据都是自顶向下的。

假设有祖先组点A,中间经过结点B, C,然后到结点D,D需要从A中获取数据f,那按照自顶向下数据流转,f需要依次传递给B及C,最后才到C。这样开发极为不灵活,成本也比较高。所有Flutter需要有跨结点(只能是祖先后代节点,不能跨兄弟节点)高效传递数据的方案。

大体意思如下:

InheritedWidget 是在树中高效向下传递信息的基类部件;

调用[BuildContext.inheritFromWidgetOfExactType]方法可以从 BuildContext 中获取到最近的 InheritedWidget 类型的实例;

在 InheritedWidget 类型的控件被引用,也就是调用过 inheritFromWidgetOfExactType 方法后,当 InheritedWidget 自身状态改变时,会导致引用了 InheritedWidget 类型的子控件重构(rebuild)。

这里随便定义一个人 Person 类。

创建一个类继承 InheritedWidget,并实现 updateShouldNotify 方法。

之前说到调用[BuildContext.inheritFromWidgetOfExactType]方法可以从 BuildContext 中获取到最近的 InheritedWidget 类型的实例,所以此处定义一个静态的 of 方法,通过传入的 context 获取到最近的 InheriedDataWidget 实例。

1.定义数据模型

这里随便定义一个 Person 类。

2.自定义 InheritedWidget 控件类

创建一个类继承 InheritedWidget,并实现 updateShouldNotify 方法。

之前说到调用[BuildContext.inheritFromWidgetOfExactType]方法可以从 BuildContext 中获取到最近的 InheritedWidget 类型的实例,所以此处定义一个静态的 of 方法,通过传入的 context 获取到最近的 InheriedDataWidget 实例。

3.InheriedDataWidget 的使用

InheriedDataWidget 使用起来也很简单,它本身也是一个控件,只要在任意一个页面的子控件调用其构造方法就行,这里我们定义一个形如的 Widget 树。

WidgetA 是一个 StatefulWidget 类型的控件,可以调用 setState 刷新,如果是继承人 Stateless 类型的控件,那我们也可以通过 Stream 或者其他方式刷新数据,感兴趣的请看[什么是 Stream? Dart

WidgetA1_1 类

WidgetA1_2 类

WidgetA1_3 类

当我们点击 floatingActionButton 的时候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都会更新 Person 的信息,而且每点 floatingActionButton 一次, 当我们点击 floatingActionButton 的时候,WidgetA1, WidgetA1_1, WidgetA1_2 的控件都会更新 Person 的信息,而且每点 floatingActionButton 一次,都会输出:

如果我们试图在和 WidgetA 的同一层级的兄弟节点去访问 InheriedDataWidget 的 Person 数据,是不行的,因为父节点中并没有插入 InheriedDataWidget。

把 WidgetB 和 WidgetA 保持同一节点

这也体现了 Inheried(遗传) 这一单词的特性,遗传只存在于父子。兄弟不存在遗传的关系。

这种数据共享的方式在某些场景还是很有用的,就比如说全局主题,字体大小,字体颜色的变更,只要在 App 根层级共享出这些配置数据,然后在触发数据改变之后,所有引用到这些共享数据的地方都会刷新,这换主题,字体是不是就很轻松,事实上 Theme.of(context).primaryColor 之流就是这么干的。

以上就是有关InheritedWidget的使用。

自己也是从事Android开发5年有余了;整理了一些Android开发技术核心笔记和面经题纲,有关更多Android开发进阶技术资料、面经题纲、核心技术笔记; 想要进阶自己、拿高薪的同学请私信我回复“核心笔记”或“面试”领取!


文章名称:flutter开发技术,Flutter架构
网页地址:http://scjbc.cn/article/hooejp.html

其他资讯