关于flutter:Flutter-应用程序布局的最佳实践

Flutter 中简直所有的货色都是一个小部件,当你编写小部件时,你能够构建一个布局。例如,您能够在列小部件中增加多个小部件以创立垂直布局。随着您持续增加更多小部件,您的 Flutter 应用程序布局将变得越简单。 在本文中,我将介绍一些在布局 Flutter 应用程序时要施行的最佳实际。 在 Flutter 中应用 SizedBox 代替 Container有许多应用状况下,你须要应用占位符。让咱们看一下上面的例子: return _isLoaded ? Container() : YourAwesomeWidget();Container 是一个很棒的小部件,您将在 Flutter 中宽泛应用它。 Container() 扩大以适应父级提供的束缚,并且不是 const 构造函数。 另一方面,SizedBox 是一个构造函数,创立一个固定尺寸的盒子。宽度和高度参数能够为空,以示意盒子的尺寸不应受到相应维度的限度。 因而,当咱们实现占位符时,应该应用 SizedBox 而不是 Container。 return _isLoaded ? SizedBox() : YourAwesomeWidget();应用 if 条件而不是三元运算符语法在布局 Flutter 应用程序时,通常须要有条件地渲染不同的小部件。您可能须要依据平台生成一个小部件,例如: Row( children: [ Text("Majid"), Platform.isAndroid ? Text("Android") : SizeBox(), Platform.isIOS ? Text("iOS") : SizeBox(), ]);在这种状况下,您能够删除三元运算符并利用 Dart 的内置语法在数组中增加 if 语句。 Row( children: [ Text("Majid"), if (Platform.isAndroid) Text("Android"), if (Platform.isIOS) Text("iOS"), ]);您还能够应用扩大运算符扩大此性能,并依据须要加载多个小部件。 ...

March 20, 2022 · 3 min · jiezi

关于flutter:2022-Flutter-Performance-性能调试工具-devTools

前言Flutter Release 发版前必定须要性能测试的,明天咱们就一起来探讨下,这个话题能够聊的很深刻,我这里就做个抛砖引玉吧。 本节指标调试工具应用 PerformanceCPU ProfilerMemoryPackage SizeInspector Widget 描边性能优化几点倡议视频https://www.bilibili.com/vide... 参考Flutter 性能剖析https://flutter.cn/docs/perf/...使用性能视图 (Performance view)https://flutter.cn/docs/devel...Using the app size toolhttps://docs.flutter.dev/deve...注释devTools performance 打开方式调试必须真机!vscode "flutterMode": "profile" 这个选项关上 命令模式关上 open devTools 抉择在浏览器中关上android studio / intellij 一键进入 profile 模式,很简略 点击 Open devTools 间接进入浏览器performance cpu 排查退出测试代码 void imBusy() { for (var i = 0; i < 9999999; i++) {} } @override Widget build(BuildContext context) { imBusy(); ...视图 UI 个别就是 cpu 了Raster 能够了解成 gpu色彩偏红就是耗时长Timeline 最上面的一条就是你的代码栈 为了不便排查 勾选这三个我的项目,剩下的就是你本人的函数Cpu Profile > Cpu Flame Chart 图标能查看具体的函数CPU Profiler 排查 ...

March 19, 2022 · 2 min · jiezi

关于flutter:Dart基础知识汇总

1 介绍Dart是由谷歌开发的计算机编程语言,它能够被用于web、服务器、挪动利用 和物联网等畛域的开发。 Dart诞生于2011年,号称要取代JavaScript。然而过来的几年中始终不温不火。直到Flutter的呈现当初被人们从新器重。 要学Flutter的话咱们必须首先得会Dart。 官网:https://dart.dev/ 2 环境搭建要在咱们本地开发Dart程序的话首先须要装置Dart SDK。 官网文档:https://dart.dev/get-dart。 windows环境http://www.gekorm.com/dart-wi...。 mac环境参考上一篇文章, Mac搭建Flutter+Dart开发环境。 3 开发工具Dart的开发工具有很多: IntelliJ IDEA 、 WebStorm、 Atom、VS Code等 这里咱们次要给大家解说的是如果在VS Code中配置Dart。 1 装置VS Code https://code.visualstudio.com/。 2 找到VS Code插件装置dart。 3 找到VS Code插件装置code runner Code Runner 能够运行咱们的文件。 4 变量 常量 命名规定变量dart是一个弱小的脚本类语言,能够不事后定义变量类型 ,主动会类型推倒。 dart中定义变量能够通过var关键字能够通过类型来申明变量。 留神:var 后就不要写类型,写了类型不要var 两者都写 var a int = 5; 报错。 var str = 'this is var';String str = 'this is var';int str = 123;常量final 和 const修饰符 const值不变 一开始就得赋值。 ...

March 17, 2022 · 14 min · jiezi

关于flutter:Flutter-图片库高燃新登场

作者:王振辉(新宿) 去年,闲鱼图片库在大规模的利用下获得了不错的问题,但也遇到了一些问题和诉求,须要进一步的演进,以适应更多的业务场景与最新的 flutter 个性。比方,因为齐全摈弃了原生的 ImageCache,在与原生图片混用的场景下,会让一些低频的图片反而占用了缓存;比方,咱们在模拟器上无奈展现图片;比方咱们在相册中,须要在图片库之外再搭建图片通道。 这次,咱们奇妙地将外接纹理与 FFi 计划组合,以更贴近原生的设计,解决了一系列业务痛点。没错,Power 系列将新增一员,咱们将新的图片库命名为 「PowerImage」! 咱们将新增以下外围能力: 反对加载 ui.Image 能力。在去年基于外接纹理的计划中,应用方无奈拿到真正的 ui.Image 去应用,这导致图片库在这种非凡的应用场景下无能为力;反对图片预加载能力。正如原生precacheImage一样。这在某些对图片展现速度要求较高的场景下十分有用;新增纹理缓存,与原生图片库缓存买通!对立图片缓存,防止原生图片混用带来的内存问题;反对模拟器。在 flutter-1.23.0-18.1.pre之前的版本,模拟器无奈展现 Texture Widget;欠缺自定义图片类型通道。解决业务自定义图片获取诉求;欠缺的异样捕捉与收集;反对动图。Flutter 原生计划在咱们新计划开始之前,先简略回顾一下 flutter 原生图片计划。 原生 Image Widget 先通过 ImageProvider 失去 ImageStream,通过监听它的状态,进行各种状态的展现。比方frameBuilder、loadingBuilder,最终在图片加载胜利后,会 rebuild 出 RawImage,RawImage 会通过 RenderImage 来绘制,整个绘制的外围是 ImageInfo 中的 ui.Image。 Image:负责图片加载的各个状态的展现,如加载中、失败、加载胜利展现图片等;ImageProvider:负责 ImageStream 的获取,比方零碎内置的 NetworkImage、AssetImage 等;ImageStream:图片资源加载的对象。在梳理 flutter 原生图片计划之后,咱们发现是不是有机会在某个环节将 flutter 图片和 native 以原生的形式买通? 新的计划咱们奇妙地将 FFi 计划与外接纹理计划组合,解决了一系列业务痛点。 FFI正如结尾说的那些问题,Texture 计划有些做不到的事件,这须要其余计划来互补,这其中外围须要的就是 ui.Image。咱们把 native 内存地址、长度等信息传递给 flutter 侧,用于生成 ui.Image。 首先 native 侧先获取必要的参数(以 iOS 为例): _rowBytes = CGImageGetBytesPerRow(cgImage); CGDataProviderRef dataProvider = CGImageGetDataProvider(cgImage); CFDataRef rawDataRef = CGDataProviderCopyData(dataProvider); _handle = (long)CFDataGetBytePtr(rawDataRef); NSData *data = CFBridgingRelease(rawDataRef); self.data = data; _length = data.length;dart 侧拿到后, ...

March 17, 2022 · 3 min · jiezi

关于flutter:Mac搭建FlutterDart开发环境

1 下载 Flutter SDKhttps://flutter.dev/docs/development/tools/sdk/releases?tab=macos举荐下载Stable channel, 即稳定版 2 解压SDK把下载好的 Flutter SDK 轻易解压到你想装置SDK的目录, 比方 查看以后渠道 flutter channel 可应用以下命令切换渠道 flutter channel masterflutter upgrade如果遇到报错git: Aborting Switching channels failed with error code 1. cd 到flutter装置目录, 执行 git checkout . 而后从新执行 flutter channel masterflutter upgrade可能两头会失败几次, 多试几次就能够了 3 装置DartDart官网 https://dart.dev/get-dart 装置Homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" 装置dart brew tap dart-lang/dart brew install dart如果报错Error: An exception occurred within a child process: DownloadError: Failed to download resource "dart" Download failed: https://storage.googleapis.com/dart-archive/channels/stable/release/2.7.2/sdk/dartsdk-macos-x64-release.zip ...

March 16, 2022 · 2 min · jiezi

关于flutter:Flutter-毁了客户端和-Web-开发

Google 重磅公布了专为 Web、挪动和桌面而构建的 Flutter 2.0!将 Flutter 从挪动开发框架扩大成可移植框架,因此开发者无需重写代码即可将利用扩大至桌面或网页。看似为了帮忙Web和挪动开发者,实际上不然,而本文作者认为,当初不应该再去想创立一个须要部署到所有平台的应用程序,Flutter反而毁了Web和挪动开发。 以下为译文: 大家好,我是一名软件开发人员,我叫 Luke。 因为我抉择了这个相当大胆的题目,为了防止误会,我要对其进行具体的解释。从技术角度来讲,Flutter 确实是一个跨平台的框架。也不止其,所有跨断技术都是十分蹩脚的设计。 然而,我有点不同的认识。 从 Flutter 2.0 公布以来,我就察觉到它被炒的有点过了。但不应该再去想创立一个须要部署到所有平台的应用程序,Flutter反而毁了Web和挪动开发。 请不要误会,我并不是要否定它,其实我也是 Flutter 的粉丝,亦将判若两人的拥戴它。 我在日常工作中常常应用 Flutter 来开发 iOS 和 Android 应用程序。因为早前我是用 Kotlin 或者 Swift 来开发原生的利用,反对多种个性,如:扫描 / 页面辨认、pin/biometric 应用程序认证、告诉、firebase 统计和一些高级的用户流,当初用 Flutter 来开发利用,我对 Flutter 的优缺点的理解更加透彻。 1、六大平台 通过往年的 Flutter Engage 会议咱们可知曾经能够应用 Flutter 在 iOS、 Android、 Mac、 Windows、 Linux 和 Web 这六个平台中的任何一个平台上开发利用。这太棒了!但事件远没有这么简略...你确实能够在这 6 个平台上部署你的应用程序,然而说实话,我很少这么做。我很难设想一个人会在不同的平台上部署同一个应用程序,我认为应该依据不同的平台特点应用不同的设计模式。在大型设施上应用底部弹窗、应用程序条、简洁的列表就很顺当。一般来说,适宜在挪动设施上的组件和设计模式在桌面设施上却不合时宜,反之亦然。 我的一个十分好的敌人 Filip Hracek 在 Flutter Engage 演讲中提到“神奇的设计开发者”的相干话题,我十分同意他的认识。我认为须要有更多的开发者真正晓得他们正在做的是什么,而且不是自觉地跟从迭代面板。 Scrum Sprint 是一个可反复的固定工夫框,在这个工夫框内发明一个高价值的产品。-- 维基百科 强烈推荐大家观看 Filip 在 Youtube 上的相干视频片段https://www.youtube.com/watch...。 ...

March 15, 2022 · 1 min · jiezi

关于flutter:在-Flutter-中更快地加载图像资源

咱们能够把图片放在咱们的assets文件夹中,但如何更快地加载它们呢?这里有一个Flutter中的机密函数能够帮忙咱们做到这一点--precacheImage()。 很多时候(尤其是在 Flutter Web 中),您的本地资源图像须要破费大量工夫在屏幕上加载和渲染! 这对用户来说是不利的,特地是如果该图像是你的屏幕的背景图像。如果图像是屏幕上的任何组件,咱们依然能够显示闪动的微光(shimmer)或其余货色,以便用户晓得图像正在加载。然而,咱们不能为背景图片显示闪动的微光,对吗? 咱们在 Flutter 中有一个简略而有用的办法,咱们能够用它来更快地加载咱们的资产图像——precacheImage()! precacheImage 将ImageProvider和context作为必要参数,并返回 Future<void>。 Future<void> precacheImage( ImageProvider<Object> provider, BuildContext context, {Size? size, ImageErrorListener? onError})此办法将图像预取到图像缓存中,而后无论何时应用该图像,它的加载速度都会快得多。然而,ImageCache 不容许保留十分大的图像。 因为在此须要上下文,因而咱们能够在可拜访上下文的任何函数中增加 precacheImage()。咱们能够将雷同的内容放在第一个屏幕的 didChangeDependencies() 办法中! 例如 void didChangeDependencies() { precacheImage(AssetImage("assets/logo.png"), context); precacheImage(AssetImage("assets/home_bg.png"), context); super.didChangeDependencies(); }下面的例子将把 logo.png 和 home_bg.png 缓存到ImageCache中。所以当初,无论何时咱们应用这张图片,它都会加载得更快。 这是一个不便的技巧,以加载你的图像资产更快!上面是应用和不应用 precacheImage() 加载图像所需工夫的一个小统计 你能够看到,开始的 3 个打印语句是没有 precacheImage 的,每次都破费近 10 毫秒。当初,下一个是 precacheImage,它在缓存中存储图像须要 14 毫秒。随后的加载只用了 5 毫秒。所以咱们能够得出结论,它将加载工夫缩小到近 50%!您能够在 GitHub 上找到雷同的代码!

March 9, 2022 · 1 min · jiezi

关于flutter:Flutter-ChartSpace通过跨端-Canvas-实现图表库

基于Flutter 的图形语法库,通过跨端 Canvas ,将基于 Javascript 的图形语法库 ChartSpace 扩大至 Flutter 端作者:字节跳动终端技术——胡珀 背景数据平台有个基于图形语法的图表库 ChartSpace ,反对 web/h5/mini program,当初收到业务诉求,要反对到 Flutter 端。 为不便了解,略微解释下图形语法的概念,曾经理解的小伙伴能够跳过这一段。 图形语法图形语法(grammar of graphics) 是通过一套语法来形容任意图形,次要来自 Wilkinson 的《The Grammar of Graphics》,可参考文章:https://zhuanlan.zhihu.com/p/... 图形语法与个别的图表次要区别在于:图形语法只有批改下语法形容,就能失去齐全不同的图形,而个别的图表须要减少图表类型。图形语法可形容的图形是近乎有限的,而图表类型是无限的。 举个例子(截取自:https://segmentfault.com/a/11...): 如果咱们基于图形语法绘制了柱状图 将语法中的坐标系换成极坐标后,会变成玫瑰图 语法中调整坐标度量,并减少不同色彩后,变成了更欠缺的玫瑰图 持续调整语法参数,最终可失去饼图 在这个例子中,如果用个别图表(如 ECharts),须要至多4个图表类型,图表数据的格局也可能存在区别。但应用图形语法形容,只须要调整不同的语法参数,就能失去不同的图形。 图形语法通过调整语法参数,失去不同的图形,给数据的表白提供了更大的空间,属于更业余的图表引擎,但同样也带来了较为简单的语法规定。 基于图形语法,前端(JS语法)罕用的图表库: G2:蚂蚁金服基于图形语法的图表库,图形语法通过 js 语法应用const ds = new DataSet();const chart = new Chart({ ...});...const dv2 = ds.createView().source(dv1.rows);dv2.transform({ type: 'regression', method: 'polynomial', fields: ['year', 'death'], bandwidth: 0.1, as: ['year', 'death']});const view2 = chart.createView();view2.axis(false);view2.data(dv2.rows);...chart.render();Vega:开源的图形语法框架,图形语法通过 json 配置应用{ width : 500, height : 200, config : { axis : { grid : true, gridColor : #dedede } }, ...}ChartSpace:字节跳动基于图形语法的图表库,图形语法通过 json 配置应用,语法与 Vega 相近{ type : line , data : [], labels : { visible : false }, axes : [ { orient : left }, { orient : bottom } ], xField : x , yField : y }在跨端,跨语言的状况下,json 配置的语法领有更好的多端一致性。后端保留一套雷同的 json 配置,能够在多端绘制出雷同的图形。 ...

March 9, 2022 · 3 min · jiezi

关于flutter:Flutter-重构去哪儿QTalk

QTalk 是去哪儿网外部的一个 IM 沟通工具,同时集成了很多外部的零碎,比方 OA 审批,门禁打卡,销假审批,预约会议室,驼圈(驼厂朋友圈)等性能;不便外部办公沟通、交换的同时,也为无纸化办公,流程审批等提供了反对。 一、原有产品框架在决定 Flutter 重构之前,咱们盘点了现有的 QTalk 工程架构的问题,次要体现为: 各端差异性大:Android、iOS 以及 QT 开发框架 (一个 C++桌面端跨平台解决方案) 三端逻辑代码差别大,代表性的有 Web 加载逻辑,挪动端 React Native 页面加载逻辑等,排查问题本源时 3 端都会有不同的状况,解决方案也不雷同。研发效率低:须要保护 3 套代码,在现有人力资源下,保障性能残缺按时上线曾经比拟吃紧,还须要及时解决线上各种问题。架构档次较差:各端在架构设计上分层各不相同且不清晰,数据流推送方向简单是次要的两个问题。原生代码复杂度高:蓝色区域代表了应用原生平台能力的代码,它们在各平台相互之间不可复用且容易在版本升级中呈现适配问题,在实现需求的时候容易呈现各端体现不统一返工的状况。为了升高开发成本,进步开发效率,尽可能的将代码在各个平台进行复用,于是咱们决定重构 QTalk。 二、为什么要选 FlutterFlutter 的劣势是渲染性能高与抹平了各端差别,本源在于 Flutter 采纳了自主渲染引擎把控了渲染流程,保障了效率,相当于一个利用跑在了游戏引擎里。 以往就有人心愿用 cocos2d 或者 unity 来制作利用,达到跨端统一与节俭工时的目标,然而游戏引擎渲染是逐帧渲染,原生(iOS、Android)渲染形式是业务驱动,即有模型改变的状况下才渲染,相比之下游戏的渲染形式对性能耗费过大,包大小多倍减少,而 Flutter 通过对渲染流程的革新根本解决了这些问题,Flutter 在渲染时与原生渲染一样,都会产生渲染树,只有渲染树产生扭转的时候,重绘制才会启动,而绘制个别也只产生在有扭转的区域。 因 QTalk 开发资源紧缺,所以须要一个跨平台框架来晋升效率。同时 QTalk 也是公司内平时沟通的次要形式,页面流畅性须要有保障。QTalk 罕用的长短连贯、长列表、Web 等,Flutter 官网和社区也有一个良好的反对。混合开发在 Flutter 2.0 中也失去官网引擎的反对,所以咱们决定应用 Flutter 来开发新版 QTalk。 三、Flutter 版 QTalk 框架能够看到,数据层来源于推送或 http 或者长连贯,解决实现后变成 Flutter 中的 IMMessage 类型对象,在各个模块中解决数据库存储与交互逻辑层将数据处理结束之后能够应用订阅者模式散发到各个界面应用,而下层的UI层应用Flutter进行开发,屏蔽了各层的差别,达到了最大。 相比于旧的架构,新的架构带来了如下的劣势: 业务体现层根本抹平了各端差别,咱们用一套代码实现了5端的UI ( Android、iOS、Mac、Windows、Linux), UI 整体代码复用率达到 80% 以上,防止了原有各端的体现差别带来的UI适配额定工作量。逻辑与数据层除了个别能力(例如推送)必须应用原生代码,其余性能都 Dart 的对立实现,在保护和做新需要时工时缩小约 50%。在整个 APP 数据流动过程中,所有对于界面的数据都应用单向数据流,同时正当分层,升高了利用复杂度,所有组件都不须要保留状态,只负责依据数据源渲染。四、遇到的问题4.1 混合栈QT 中大部分页面都是能够应用 Flutter 重构的 IM 业务页面,然而另外一些页面面临更新频繁,保护方不适合放在 IM 团队的问题,例如 QT 发现页,应用 ReactNative 开发,QT 只作为入口展现,所以咱们须要一套混合 ReactNative 页面与 Flutter 的技术计划,当初 Flutter 的支流混合技术栈有 2 种: ...

March 9, 2022 · 4 min · jiezi

关于flutter:Flutter-设计模式|工厂模式家族

文/ 杨加康,CFUG 社区成员,《Flutter 开发之旅从南到北》作者,小米工程师 在围绕设计模式的话题中,工厂这个词频繁呈现,从 简略工厂 模式到 工厂办法 模式,再到 形象工厂 模式。工厂名称含意是制作产品的工业场合,利用在面向对象中,牵强附会的成为了比拟典型的创立型模式。 从模式上讲,工厂能够是一个返回咱们想要对象的一个办法/函数,即能够作为构造函数的一种形象。本文,就带大家应用 Dart 了解它们的各自的实现,以及它们之间的关系。 简略工厂 & factory 关键字简略工厂模式 不在 23 种 GoF 设计模式中,却是咱们最常应用的一种编程形式。其中次要波及到一个非凡的办法,专门用来提供咱们想要的实例对象(对象工厂),咱们能够将这个办法放到一个独自的类 SimpleFactory 中,如下: class SimpleFactory { /// 工厂办法 static Product createProduct(int type) { if (type == 1) { return ConcreteProduct1(); } if (type == 2) { return ConcreteProduct2(); } return ConcreteProduct(); }}咱们认为该办法要创立的对象同属一个 Product 类(抽象类),并通过参数 type 指定要创立具体的对象类型。Dart 不反对 interface 关键词,但咱们能够应用 abstract 以抽象类的形式定义接口,而后各个具体的类型继承实现它即可: /// 抽象类abstract class Product { String? name;}/// 实现类class ConcreteProduct implements Product { @override String? name = 'ConcreteProduct';}/// 实现类1class ConcreteProduct1 implements Product { @override String? name = 'ConcreteProduct1';}/// 实现类2class ConcreteProduct2 implements Product { @override String? name = 'ConcreteProduct2';}当咱们想要在代码中获取对应的类型对象时,只须要通过这个办法传入想要的类型值即可,咱们不用关怀生产如何被生产以及哪个对象被抉择的具体逻辑: ...

March 8, 2022 · 4 min · jiezi

关于flutter:Flutter-2021-中的按钮

在本文中,咱们将介绍令人惊叹的 Flutter 按钮,它们能够帮忙所有初学者或专业人士为古代利用程序设计丑陋的 UI。 首先让我通知你对于 Flutter 中按钮的一件重要事件,在flutter最新版本中以下Buttons在fluter中被废除了: 废除的举荐的代替RaisedButtonElevatedButtonOutlineButtonOutlinedButtonFlatButtonTextButton那么让咱们来摸索一下 Flutter 中的按钮。 Elevated ButtonStadiumBorder ElevatedButton( onPressed: (){}, child: Text('Button'), style: ElevatedButton.styleFrom( shadowColor: Colors.green, shape: StadiumBorder(), padding: EdgeInsets.symmetric(horizontal: 35,vertical: 20)),) RoundedRectangleBorder ElevatedButton( onPressed: (){}, child: Text('Button'), style: ElevatedButton.styleFrom( shadowColor: Colors.green, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ),),CircleBorder ElevatedButton( onPressed: () {}, child: Text('Button'), style: ElevatedButton.styleFrom( shape: CircleBorder(), padding: EdgeInsets.all(24), ),)BeveledRectangleBorder ElevatedButton( onPressed: () {}, child: Text('Button'), style: ElevatedButton.styleFrom( shape: BeveledRectangleBorder( borderRadius: BorderRadius.circular(12) ), ),)Outlined ButtonStadiumBorder ...

March 7, 2022 · 1 min · jiezi

关于flutter:用React写flutter-app

豆皮粉儿们,大家好呀,明天这一期,由字节跳动数据平台的“奕轩”同学给大家带来如何用React写flutter app。 作者:奕轩基本概念flutter谷歌推出的挪动端框架,特点是多端高度一致性,性能好,蕴含丰盛的安卓和ios格调的组件,应用dart作为开发语言 长这样⬇️ mxflutter一句话:让js以dart和flutter的模式写app 长这样⬇️ https://github.com/mxflutter/... react react架构 援用自Remax - 应用真正的 React 构建小程序 关键点ReactReconciler保护VirtualDOM,fiber算法,决定VirtualDOM的所有更新VirtualDOM的渲染由各个renderer实现:react-dom、react-nativeComponent组件宿主组件宿主能了解的最小单位的组件,浏览器中是div,span,h1等,react-native中是View,Text,Image等,宿主元素是一个字符串 复合组件用宿主组件或其余复合组件组成的组件,是一个class component或function component Element应用React.createElement创立的对象,用来形容视图节点,能够了解为组件的实例长这样⬇️ 实现根本思维定义一种虚构节点类VNode,并定义VNode的append、remove、insert等办法,利用react-reconciler提供的api在创立节点、插入节点、更新节点等接口中对VNode进行更新。这样,在ReactReconciler每次对VirtualDOM更新时咱们都能晓得更新了什么,并且把更新的内容转成咱们意识的构造,保护一个VNode tree,用它渲染widget tree 具体过程初始代码⬇️ React.createElement ⬇️ ReactReconciler+VNode=NodeTree ⬇️ 递归渲染⬇️ 外围上述过程最要害的在于如何将一个react element tree转换为咱们可能进行递归的节点树 流程图 react-reconcilerreact-reconciler 能够认为是一组hooks(相似于 git hooks,而非 react hooks),去填充它裸露进去的这些生命周期函数,就能够将 React 利用到任意“宿主”零碎中 长这样⬇️ react-reconciler做了什么? 在首次渲染过程中构建出vDOM tree,后续须要更新时(setState()),diff VirtualDOM tree失去 change,并把node change更新(patch)到NodeTree VNodeVNode是VirtualDOM的最小单位,在react-reconciler的hook办法中去创立VNode、插入子VNode、删除子VNode等 长这样⬇️ BridgeBridge的作用是桥接ReactReconciler和mxflutter,当VNode有更新时,VNode持有的Bridge将diff node更新到mxflutter 将来咱们的指标是现有我的项目能够通过越少越好的批改能跑在app上, 上述原理只解决了dom映射的问题,还有以下问题须要被解决 DOM:还须要反对selectorBOM:编译时替换为app框架上的对象第三方包:初步构想是各平台保护本人的包,或应用web-component事件处理:还没想好The End

March 7, 2022 · 1 min · jiezi

关于flutter:20个你应该了解的Flutter库

在本文中,咱们将探讨20个最有用和最罕用的库,许多开发人员都喜爱它们,如果你从事flutter的开发工作,你应该晓得这一点。而所有这些都反对安卓和IOS零碎。 1 . Google Map目前大多数应用程序都须要谷歌Maps,这个库为您提供了谷歌Maps应用程序中须要的许多服务。甚至你也能够用本人的形式定制。 GoogleMap( mapType: MapType.hybrid, initialCameraPosition: _kGooglePlex, onMapCreated: (GoogleMapController controller) { _controller.complete(controller); }, ),2 .url_launcher这个库反对您启动URL到您的web浏览器,他们也反对启动您的本机模式URL,如电话,短信,电子邮件等。 _launchURL() async { const url = 'https://flutter.dev’; if (await canLaunch(url)) { await launch(url); } else { throw 'Could not launch $url’; } }3 .Firebase packages (FlutterFire)这不是一个独自的,它是一组汇合库,firebase反对您的flutter应用程序。 咱们在应用程序中应用 firebase 来实现多种不同的办法,例如消息传递、数据库等。 因而,在这里你能够依据你的要求找到所有这些货色,它为此独自提供了一个库。 4 .Provider状态治理是咱们应用程序的重要组成部分,Provider 在咱们以后须要的中央提供以后的数据模型。 Provider是 InheritedWidget 的包装器,能够应用更少的样板代码更轻松地应用。 Provider 是最根本的 Provider widget类型。您能够应用它为widget树中的任何地位提供值(通常是数据模型对象)。然而,当该值更改时,它不会帮忙您更新widget树。 5 .Bloc这也是一个状态治理库。Bloc(Business Logic Component)设计模式,这是一种相似于MVVM模式的货色。 Bloc widget是你实现所有业务逻辑所需的根本组件。要应用它,请扩大Bloc类并重写 mapEventToState 和 initialState 办法。 6 .Getx它也是一个状态治理库。GetX 提供了状态治理、依赖注入和路由治理解决方案的组合,能够很好地协同工作。 ...

March 3, 2022 · 1 min · jiezi

关于flutter:Flutter实现仿京东地址选择组件

Flutter实现仿京东地址抉择组件,省市区三级级联选择器,数据为模仿数据,可依据实在接口数据革新,也可扩大成为省市区街道四级抉择,下载地址:https://download.csdn.net/dow...效果图如下:次要实现代码如下:// 省TabView _provinceTabView() { return ListView.builder( itemBuilder: (BuildContext context, int index) { return InkWell( onTap: () => areaChange(0, index), child: _nameBar(provinceList[index]['name'], provinceActive == index)); }, itemCount: provinceList.length);} // 市 _cityTabView() { return ListView.builder( itemBuilder: (BuildContext context, int index) { return InkWell( onTap: () => areaChange(1, index), child: _nameBar( provinceList[provinceActive]['city'][index]['name'], cityActive == index)); }, itemCount: provinceList[provinceActive]['city'].length);} // 区县 _areaTabView() { return ListView.builder( itemBuilder: (BuildContext context, int index) { return InkWell( onTap: () => areaChange(2, index), child: _nameBar( provinceList[provinceActive]['city'][cityActive]['area'][index]['name'], areaActive == index)); }, itemCount: provinceList[provinceActive]['city'][cityActive]['area'].length);} ...

March 1, 2022 · 1 min · jiezi

关于flutter:阿里卖家-Flutter-for-Web-工程实践

作者:马坤乐(坤吾) Flutter 自 2015 年首次亮相以来,通过了多年的倒退曾经相当成熟,在阿里、美团、拼多多等互联网公司都有宽泛的利用。在 ICBU 阿里卖家上 90+% 的新业务应用 Flutter 开发,ICBU 客户端开发组领有泛滥的 Flutter 开发人员。 Flutter for Web (FFW) 晚期试验版于 2019 年公布,在过后曾经有很多感兴趣同学对其进行调研,过后因为刚公布存在诸多问题不适宜在生产环境中应用。在往年(2021)三月份,Flutter 2.0 公布,FFW 正式进入 stable 分支。 阿里卖家外贸资讯版块次要应用 Flutter 开发,在本财年的指标中,外贸资讯的App外推广为开源引流的重要一环。App外资讯推广须要一个承载内容Web页面,对该Web页面的要求如下: 复刻App端相干页面的 UI、性能(次要蕴含一个dart编写的自定义html解析渲染引擎)【次要工作量】疾速上线App端性能同步因为不足前端同学的反对,想要实现此页面只能由 App 端上同学本人投入,通过肯定的思考咱们抉择了 FFW,理由如下: 切换到前端技术栈 Rax 等老本稍高,同时指标页面性能复刻须要较多工夫应用 FFW 指标页面上绝大部分代码可复用端上现成 dart 代码App 端上 Flutter 技术栈同学笼罩广通过以上思考,正式开启 FFW 填坑之旅。 Demo目前阿里卖家FFW相干页面已上线,从 FFW 公布至今产物 js 文件大的问题就始终存在,实践上会很影响页面加载体验,理论测试中察看到在 PC、挪动设施上加载体验尚可,运行很晦涩,相干 Demo 如下: 外投内容展现页 demo:https://alisupplier.alibaba.c...阿里卖家 App 下载页面:https://alisupplier.alibaba.c...问题总览创立 FFW 工程比较简单,Flutter 切换到 stable 版本,之后运行命令 flutter create xxxProject 进入工程后点击运行一个 Demo 工程便可运行起来。要将 FFW 利用到理论的工程中,须要思考的是工程的问题和如何融入阿里的体系的问题,如:怎么公布、开发流程如何管控、怎么申请接口等,总结如下: ...

February 25, 2022 · 6 min · jiezi

关于flutter:dart系列之集合使用最佳实践

简介dart中有四种汇合,别离是Set,List,Map和queues。这些汇合在应用中须要留神些什么呢?什么样的应用才是最好的应用办法呢?一起来看看吧。 应用字面量创立汇合对于罕用的Set,Map和List三个汇合来说,他们是有本人的无参构造函数的: factory Set() = LinkedHashSet<E>; external factory Map(); @Deprecated("Use a list literal, [], or the List.filled constructor instead") external factory List([int? length]);能够看到Set和Map是能够应用构造函数的。然而对于List来说,无参的构造函数曾经不举荐应用了。 对于Set和Map来说,能够这样结构: var studentMap = Map<String, Student>();var ages = Set<int>();然而dart官网举荐间接应用字面量来创立这些汇合,如下所示: var studentMap = <String, Student>{};var ages = <int>{};为什么呢?这是因为dart中的字面量汇合是十分弱小的。能够通过扩大运算符,if和for语句对汇合进行结构和扩大,如下所示: var studentList = [ ...list1, student1, ...?list2, for (var name in list3) if (name.endsWith('jack')) name.replaceAll('jack', 'mark')];不要应用.length来判断汇合是否为空对应dart的可遍历汇合来说,这些汇合并没有存储汇合的长度信息,所以如果你调用汇合的.length办法,可能会导致汇合的遍历,从而影响性能。 留神Set和List是可遍历的,而Map是不可遍历的。所以,咱们须要调用汇合的.isEmpty 和 .isNotEmpty办法来判断汇合是否为空,这样速度更快。 if (studentList.isEmpty) print('it is empty');if (studentList.isNotEmpty) print('it is not empty');可遍历对象的遍历对应Set和List这两个可遍历的汇合来说,有两种遍历办法,能够通过调用forEach() 办法或者for-in来进行遍历,如下所示: ...

February 23, 2022 · 1 min · jiezi

关于flutter:flutter好学吗该怎么学史上最全Flutter入门与实战拿走不谢

Flutter是什么Flutter是一款挪动应用程序SDK,一份代码能够同时生成iOS和Android两个高性能、高保真的应用程序。Flutter指标是使开发人员可能交付在不同平台上都感觉天然晦涩的高性能应用程序。咱们兼容滚动行为、排版、图标等方面的差别。无需挪动开发教训即可开始应用。应用程序是用Dart语言编写的,如果您应用过Java或JavaScript之类的语言,则该应用程序看起来很相熟。应用面向对象语言的教训相对有帮忙,但一些Flutter应用程序甚至是没有编程教训的人写的! Flutter的特点:1、开源也正是因为开源,所以在寰球开发者的疯狂反对下,这几年flutter飞速发展,越来越趋于欠缺,置信当前再windows,mac,linux等各个平台也能大放荣耀。真正做到一套代码多端部署。 2、稳固Flutter UI因为自绘UI,从而防止了平台层面的UI和系统升级导致的各种兼容问题。然而作为跨平台开发技术不可避免的须要去保护底层适配层和各种插件实现与原始平台的通信,这是所有跨平台的通病。 3、高效对开发者来说,应用 Flutter 开发利用非常高效。Flutter 广受好评的 Hot Reload 性能能够在 1 秒内实现代码到 UI 的更新,使得开发操作周期被大幅缩短。 4、找工作的加分项 Flutter的劣势性能弱小,晦涩Flutter比照weex和react native相比,性能的弱小是引人注目的。基于dom树渲染原生组件,很难与间接在原生视图上绘图比肩性能,Google作为一个轮子大厂,间接在两个平台上重写了各自的UIKit,对接到平台底层,缩小UI层的多层转换,UI性能能够比肩原生,这个劣势在滑动和播放动画时尤为显著。 路由设计优良Flutter的路由传值十分不便,push一个路由,会返回一个Future对象(也就是Promise对象),应用await或者.then就能够在指标路由pop,回到以后页面时收到返回值。这个反向传值的设计根本是甩了微信小程序一条街了。弹出dialog等一些操作也是应用的路由办法,简直不必放心呈现传值艰难 进步开发效率同一份代码开发iOS和Android,用更少的代码做更多的事件。 轻松迭代在利用程序运行时更改代码并从新加载(通过热重载),修复解体并持续从应用程序进行的中央进行调试。 可选动态的语言,语言个性优良Dart是一个动态语言,这也是绝对于js的一个劣势。Dart能够被编译成js,然而看起来更像java。动态语言能够防止谬误,取得更多的编辑器提醒词,极大的减少可维护性。很多js库也曾经用ts重写了,Vue3.0的底层也将全副应用ts编写,动态语言的劣势显而易见。 Flutter 到底该怎么学?真的要从头开始么?尽管 Flutter 是全新的跨平台技术,但其背地的框架原理和底层设计思维,无论是底层渲染机制与事件处理形式,还是组件化解耦思路,亦或是工程化整体办法等,与原生 Android / iOS 开发并没有本质区别,甚至还从 React Native 那里排汇了不少优良的设计理念。就连 Flutter所采纳的 Dart 语言,对于信息表白和解决的形式,也有诸多其余优良编程语言的影子。因而,从实质上看,Flutter 并没有开翻新的概念。这也就意味着,如果咱们在学习 Flutter时,可能深刻进去搞懂它的原理、设计思路和通用理念,并与过往的开发教训相结合,建设起属于本人的常识体系抽象层次,而不是仅停留在应用层 API 的应用上,就解脱了教训与平台的强绑定。 给大家分享一份超全《Flutter入门与实战》材料,帮忙大家更好的去学习Flutter。第一章、Flutter基本功能我的第一个 Flutter 利用之旅容器的盒子模型构建一个罕用的页面框架设置 App 的主色调与字体来一个图文并茂的列表给列表减少下拉刷新和上滑加载更多功能应用cached_network_image 优化图片加载体验仿一个微信价值几个亿的页面开发一个罕用的登录页面封装一个通用的文本输入框底部弹窗ModelBottomSheet详解利用CustomScrollView实现更乏味的滑动成果底部弹窗如何实现多项抉择? 第二章、Flutter路由治理App页面路由及路由拦挡实现路由参数解决初识 fluro 路由治理应用 fluro 的转场动画进步页面切换体验应用自定义转场动画实现个性化页面切换此路是我开,此树是我栽。若是没权限,403到来Flutter 2.0的路由把我搞蒙了山路十八弯的2.0路由 第三章、Flutter网络申请插件Dio初次见面,网络申请王者之dio利用 Dio申请删除数据应用 Dio的 Patch申请实现详情编辑应用 Post 申请减少动静一文搞定图片抉择及图片上传应用 GetIt 同步不同页面间数据Dio 封装之金屋藏娇Dio 之拦截器Dio之戛然而止从源码深刻理解Dio 的CancelToken小伙子,你买票了吗?手写一个长久化的CookieManagerDio之文件下载Dio 篇章总结 第四章、Flutter状态治理根底原理篇Provider篇Redux篇Mobx篇Getx篇BLOC篇状态治理系列大汇总 第五章、Flutter 动画应用 Animation 构建爱心三连动画让你的组件领有三维动效小姐姐渐现成果 ——AnimatedOpacity 应用应用 AnimatedBuilder拆散组件和动画,实现动效复用看这一颗跳动的热心—— AnimatedPadding 利用应用AnimatedSwitcher 做场景切换给小姐姐的照片调个色彩滤镜 ...

February 16, 2022 · 1 min · jiezi

关于flutter:在-Flutter-应用程序中通过定制服务进行本地化

前言猫哥在我的项目中也是有这个困惑,如何治理 多语言,如果常量定义形式,还是有点不优雅。 这篇文章的作者就提出了个不错的倡议,服务端编辑,本地文件缓存同步。 就是读取数据库啦,后端弄个界面保护保护数据,貌似是一个不错的计划。 原文https://medium.com/flutter-co... 代码https://github.com/VB10/custo... 参考https://pub.dev/packages/easy...注释许多应用程序在客户端进行本地化。这意味着,如果您的密钥有任何问题,您必须同时更新字符串和应用程序。让咱们学习自定义解决方案,当用户将扭转语言,咱们的应用程序将间接更新每个屏幕的新语言。 正如我所说的,通常咱们应用 JSON 文件等的本地化。我写了许多 Flutter 我的项目,所以我过来使本地化为咱们的客户,一般来说,我做了一个土耳其和英语版本的产品由我写的。 通常咱们像这样定义这些键,而后应用程序用键读取值。 Flutter 有许多本地化选项,特地是我在生产我的项目中屡次应用了 easy_localizaiton。这对我的所有要求都实用,但有一天,客户须要非凡的解决方案。我曾经间接要求, 你晓得咱们有一个 location ,你还指望什么?是的,Veli 咱们晓得这一点,然而咱们想要治理本地化文件在咱们的 web 服务和客户端能够更改语言到咱们的本地化列表响应。实际上,这个申请并不是什么大问题,因为咱们能够应用近程配置、 Firebase 实时配置或者简略的本地化都有自定义的后端解决方案,然而任何人都不能满足这些要求。该做甜甜圈了! 如果咱们想要更好的编码工夫,咱们必须制订打算。首先,两个应用程序的 API 端点是什么,以取得咱们反对的语言列表,应用程序将通过查看语言键带来翻译值。当应用程序用户更改应用程序中的语言时,咱们必须更改整个字符串值,而不是旧值。 咱们的步骤:应用程序和应用程序更改语言的后端端点能够是显示语言咱们将实现初始语言咱们能够依据主动接管到的新语言信息扭转整个文本的一个点。用户能够找到以后的语言值。 我用 Firebase 创立了简略的后端资源,例如: 通常我有一个定制的后端,比方 node.js,Java 等等,或者我能够抉择 Firebase 云函数,然而我只是想展现如何应用 flutter 个性定制本地化,所以咱们没有应用这个办法。 让咱们开始编码吧! 咱们晓得如何用后端端点加载语言资源。之后,我想缓存它的后端响应,因为客户端须要每次重新启动的全副数据。因而,咱们须要缓存机制,以放弃后端响应,而用户不更改语言。 我曾经抉择了 Hive 解决方案应用缓存的应用程序,因而 Hive 十分疾速,平安,和有用的解决方案为咱们。我为咱们的许多企业项目选择了 Hive。我将在这个我的项目中应用这个库: Hive - https://pub.dev/packages/hive (Cache)Vexana - https://pub.dev/packages/vexana (Network)Provider - https://pub.dev/packages/prov... (Global State)首先,咱们须要示例屏幕来显示初始语言的键值(当初我承受在更改为 tr 之后开始 en while 应用程序)。 我在上面的图片中增加了 tr 和 en 的语言值。 ...

February 15, 2022 · 1 min · jiezi

关于flutter:Flutter-屏幕采集实战分享

一、概述在视频会议、线上课堂、游戏直播等场景,屏幕共享是一个最常见的性能。屏幕共享就是对屏幕画面的实时共享,端到端次要有几个步骤:录屏采集、视频编码及封装、实时传输、视频解封装及解码、视频渲染。 一般来说,实时屏幕共享时,共享发动端以固定采样频率(个别 8 - 15帧足够)抓取到屏幕中指定源的画面(包含指定屏幕、指定区域、指定程序等),通过视频编码压缩(应抉择放弃文本/图形边缘信息不失真的计划)后,在实时网络上以相应的帧率散发。 因而,屏幕采集是实现实时屏幕共享的根底,它的利用场景也是十分宽泛的。 现如今 Flutter 的利用越来越宽泛,纯 Flutter 我的项目也越来越多,那么本篇内容咱们次要分享的是 Flutter 的屏幕采集的实现。 二、实现流程在具体介绍实现流程前,咱们先来看看原生零碎提供了哪些能力来进行屏幕录制。 1、iOS 11.0 提供了 ReplayKit 2 用于采集跨 App 的全局屏幕内容,但仅能通过控制中心启动;iOS 12.0 则在此基础上提供了从 App 内启动 ReplayKit 的能力。 2、Android 5.0 零碎提供了 MediaProjection 性能,只需弹窗获取用户的批准即可采集到全局屏幕内容。 咱们再看一下 Android / iOS 的屏幕采集能力有哪些区别。 1、iOS 的 ReplayKit 是通过启动一个 Broadcast Upload Extension 子过程来采集屏幕数据,须要解决主 App 过程与屏幕采集子过程之间的通信交互问题,同时,子过程还有诸如运行时内存最大不能超过 50M 的限度。 2、Android 的 MediaProjection 是间接在 App 主过程内运行的,能够很容易获取到屏幕数据的 Surface。 尽管无奈防止原生代码,但咱们能够尽量以起码的原生代码来实现 Flutter 屏幕采集。将两端的屏幕采集能力形象封装为通用的 Dart 层接口,只需一次部署实现后,就能开心地在 Dart 层启动、进行屏幕采集了。 接下来咱们别离介绍一下 iOS 和 Android 的实现流程。 ...

February 15, 2022 · 4 min · jiezi

关于flutter:使用-Codemagic-将-Flutter-Windows-应用程序发布到-Microsoft-合作伙伴中心

原文https://medium.com/flutter-co... 前言这篇文章最后发表在 Codemagic 博客上,由 Souvik Biswas 撰写 Flutter 容许您应用单个代码库为挪动设施、网络、桌面和嵌入式设施构建应用程序。2.0 的引入使得试用桌面应用程序变得更加容易,因为这个选项当初能够在 stable 频道上应用。 本文将帮忙您开始应用 Flutter 构建 Windows 桌面应用程序,生成一个版本 MSIX 构建,并应用 Codemagic 将该应用程序公布到微软合作伙伴核心。 如果你正在寻找一个建设 Flutter 桌面应用程序的更个别的入门指南,包含设计自适应布局,请查看这篇文章。 https://blog.codemagic.io/flu... 代码https://github.com/sbis04/flu...https://github.com/sbis04/flu... 注释为 Windows 创立一个 Flutter 应用程序在你开始创立一个新的 Flutter 应用程序之前,你应该在你的 Windows 零碎上装置 Flutter SDK。如果你没有装置 Flutter,依照装置指南这里。 https://docs.flutter.dev/get-... 如果你曾经在你的零碎上装置了 Flutter,确保版本在 2.0 以上。您能够应用 Flutter -- version 命令查看您的 Flutter 版本。要构建 Flutter 窗口应用程序,您应该在您的零碎上装置 Visual Studio 2019 。在装置 Visual Studio 时,如果你想构建 win32 应用程序,能够应用“带 c + + 的桌面开发”工作负载,如果你想构建 UWP 应用程序,能够应用“通用 Windows 平台开发”工作负载。 ...

February 13, 2022 · 5 min · jiezi

关于flutter:Flutter-子widget调用父widget方法报-Tried-calling-call

在学Flutter状态治理时,须要子Widget调用父Widget,报如下谬误:找了好一会,最初删除 () 后发现失常了,通过查问后得出以下论断,如下图所示:当然下面的 final Function onChanged ,Function 也能够不必加。

February 9, 2022 · 1 min · jiezi

关于flutter:Dart-216-现已发布

文 / Michael Thomsen, Dart 产品经理 Dart 2.16 正式公布Dart 2.16 正式版已于上周公布。只管没有新的语言个性退出,但本次版本公布蕴含了数个问题修复 (包含对安全漏洞的修复),公布 Dart package 的时候也能够指定反对的平台,pub.dev 网站也更新了全新的搜寻界面。 与 Flutter 2.10 一起公布的 Dart 2.16,依然在将旧的命令行工具迁徙到新的 dart 命令行工具。这个版本中,dartdoc和 dartanalyzer 已被弃用,别离对应新的命令是 dart doc 和 dart analyze。dartdoc、dartanalyzer 和 pub 这三个命令打算在 Dart 2.17 中彻底移除。 历史命令代替的 dart 命令弃用版本停用版本stagehanddart create2.142.14dartfmtdart format2.142.15dart2nativedart compile exe2.142.15dart2jsdart compile js2.172.18dartdevcnone2.172.18dartanalyzerdart analyze2.162.17package:analyzer_clidart analyze2.162.17dartdocdart doc2.162.17pubdart pub2.152.17查看所有打算弃用的命令的更多阐明,请参考 Dart SDK 仓库的 Issue #46100。 Dart 2.16 也蕴含了一个安全漏洞的修复,以及两个破坏性改变: dart:io 中的 HttpClient API 当初能够设置 authroization、www-authenticate、cookie和cookie2这些申请头信息。在 Dart 2.16 之前,SDK 中重定向逻辑的实现有一个破绽,当跨域重定向产生时,这些申请头 (可能蕴含敏感信息) 会被发送,在 Dart 2.16 中这些申请头已被移除,你能够浏览 CVE-2022–0451 理解更多细节。dart:io中的 Directory.rename API 调整了在 Windows 平台上的行为:与指标名称统一的目录不会被删除 (issue #47653)。在 Dart 1.x 中遗留的 Platform.packageRoot 和 Isolate.packageRoot 已被移除 (issue #47769),它们在 Dart 2.x 中不起作用。想要理解更多对于 Dart 2.16 的改变,能够查阅 更新日志。 ...

February 8, 2022 · 2 min · jiezi

关于flutter:Flutter-210正式版发布

前几天,Flutter 2.10 公布了正式版本,该版本间隔上个版本的公布还不到两个月工夫,但即便在这么短的工夫内,Flutter 曾经敞开了 1843 个问题,合并了 1525 个 PR。 在2.10版本中,次要的更新内容包含对Flutter的Windows反对的一个大更新,几个显著的性能改良,框架中的图标和色彩的新反对,以及一些工具的改良。此外,咱们还取得了一些对于删除开发频道、缩小对旧版本iOS的反对的更新,以及一些重大变动。 Flutter Windows 桌面端反对进入稳定版Flutter 跨平台框架的目标就是致力于打造一个可能构建精美的、可高度定制的、并且能够编译为机器码的跨平台利用解决方案,以充分发挥设施底层硬件的全副图形渲染能力。当初,Flutter 对 Windows 生产版本的正式反对标记着这一愿景的实现。它使 Windows 开发者也能享受到挪动开发的雷同生产力和性能。 当然,Windows 上的 Flutter 应用程序除了能够应用 iOS 和 Android 上的大部分罕用 Flutter 框架外,它们也能够依据须要应用 Win32、COM 和 Windows Runtime APIs等Windows特有的性能。同时,Google还更新了一些常见的 Flutter 插件,以反对 Windows,如相机、file_picker 和 shared_preferences等插件。 如果想要理解更多无关Flutter For Windows的内容,此文深度介绍了Windows上的Flutter架构,允以Flutter包和插件如何反对Windows。 性能改良此版本的Flutter对社区成员knopp提出的脏区域治理提供反对。如果启用此性能能够在iOS/Metal上为单个脏区域执行重绘。这一变动的益处是在一些基准上缩小了90到99个百分点的栅格化工夫(所谓栅格化,是指将矢量图形格局示意的图像转换成位图以用于显示器或者打印机输入的过程),并将这些基准上的GPU利用率从超过90%升高到不到10%,如下图所示。 并且,咱们心愿在将来的版本中将局部重绘的益处带给其余平台。 在Flutter 2.8版本中,咱们取得了图片的录制过程。在Flutter 2.10,咱们曾经开始优化构建过程。一个最显著的例子是,咱们在构建不通明层的时候基准中的帧光栅所花的工夫降落到了之前的三分之一以下。随着咱们对图像构建流程的深刻,咱们心愿可能将这种优化扩大到更多的应用场景。 在profile和release模式下,Dart代码会提前被编译为机器码。不过,这段代码的效率的要害是残缺的程序类型流剖析,它能够解锁许多编译器优化和踊跃的树状优化。然而,因为类型流剖析必须笼罩整个程序,它可能有点低廉。这个版本蕴含了一个更快的类型流剖析实现。从的来说,应用新的构建形式后,Flutter应用程序的总体构建工夫降落了约10%。 与以往的版本一样,性能加强、缩小内存应用和缩小提早是Flutter团队的须要解决的首要任务,咱们期待在将来的版本中失去进一步的改良。 iOS更新除了性能改良之外,咱们还新增了特定平台的个性和性能的加强。luckysmg能够让键盘动画是iOS上更加晦涩,当须要弹出软键盘时,新的动画成果将会更加晦涩,而不须要开发中做任何的事件。同时,咱们还改善了iOS相机插件的稳定性,修复了一些边缘状况下的解体。最初,64位iOS架构压缩指针带来了内存应用的升高。 咱们晓得,64位体系结构可能将指针示意为4字节的数据结构。当有很多对象时,指针自身占用的空间会减少应用程序的总内存应用,特地是遇到简单的应用程序时,有呈现更多的垃圾回收的状况。然而,iOS应用程序不太可能有足够的对象来申请32位地址空间,更不用说更大的64位地址空间了。 Dart 2.15版本提供了压缩指针,它能够缩小64位iOS应用程序的内存应用。相干介绍能够查看:Dart 2.15的博客文章来理解细节。 Android更新当然,这个版本也蕴含了许多针对Android的改良。咱们晓得,默认状况下,当咱们创立一个新的Flutter应用程序时,Flutter会默认反对最新版本的Android。此外,在这个版本中,咱们还主动启用了multidex反对。如果您的应用程序反对Android SDK版本低于21,并且超过64K办法限度,只需在应用flutter build appbundle或flutter build apk命令时增加--multidex属性即可。 最初,咱们还修复了社区反馈的Gradle谬误。也正是出于这个起因,咱们在创立Flutter应用程序时,须要增加最低反对的Android SDK版本,如下所示。当然,咱们持续跟踪社区反馈的问题,并在最新版本中提出修复计划。 Web 更新这个版本在Web方面也进行了一些改良。例如,在以前的版本中,当在web上滚动到多行TextField的边缘时,它不会失常滚动。这个版本为文本抉择引入了边缘滚动,当抉择挪动到文本字段之外时,字段也能够滚动以查看滚动范畴。这种新行为实用于网页和桌面利用。此外,这个版本的还提供了其余一些改良来晋升Web性能。咱们始终在寻找一种能够缩小Web性能开销的办法。在以前的版本中,咱们想把一个原生HTML小部件引入Flutter应用程序,咱们须要对HTML小部件进行笼罩重写,而后作为反对web的一部分。如果您的应用程序中有大量的原生HTML小部件,比方链接,这将减少大量的开销。在这个版本中,咱们为web创立了一个新的“非绘制平台视图”,从实质上打消了这种开销。咱们曾经利用了这个优化对链接小部件进行了解决,这意味着如果在你的Web应用程序中有很多链接,将不会有任何显著的开销。 素材在这个版本咱们对整体的配色计划也进行了降级,包含反对突变色彩。 final lightScheme = ColorScheme.fromSeed(seedColor: Colors.green);final darkScheme = ColorScheme.fromSeed(seedColor: Colors.green, brightness: Brightness.dark);ThemeData函数中有一个新的colorSchemeSeed参数,容许开发者生成须要的主题配色计划: ...

February 7, 2022 · 1 min · jiezi

关于flutter:Flutter-Windows-桌面端支持进入稳定版

Flutter 创立伊始,咱们就致力于打造一个可能构建精美的、可高度定制的、并且能够编译为机器码的跨平台利用解决方案,以充分发挥设施底层硬件的全副图形渲染能力。明天,Flutter 对 Windows 生产版本的正式反对是对这一愿景实现的重要标记。它使 Windows 开发者也能享受到挪动开发的雷同生产力和性能。 Flutter 的指标是在任何平台上为你提供杰出的构建体验,并且咱们想要打造的是:只须要应用同一套外围框架和工具实现这个指标。通过 Flutter,你能够自在打造 柔美 的应用体验,使你的品牌和设计怀才不遇;它还领有 极高 的执行速度,因为它会被间接编译为机器码;而通过反对有状态的热重载性能以提供交互式的体验,让你能够在利用运行时间接看到代码更改后的后果,从而取得 生产力 晋升。Flutter 是凋谢的,成千上万的贡献者参加到外围框架的构建,或是通过 package 和插件生态系统对其进行扩大。 <highlight>截止目前,曾经有近 50 万个应用程序应用 Flutter 进行构建</highlight> 迄今为止,咱们看到这股趋势曾经超出了咱们的预期。包含一些大公司例如 Betterment、宝马以及字节跳动等,还有 Google 外部三十多个团队都应用了 Flutter。依据 Statista 以及 SlashData 的统计,Flutter 在 2021 年曾经成为了最风行的跨端 UI 工具包。 咱们本人的数据也能反对这一点,在 2021 年四个季度的开发者考察中,有 92% 的 Flutter 开发者对咱们提供的工具表示满意。(对于另外 8% 的人,咱们正在聆听你的反馈,心愿也能失去你的称心)。 这其中独特的需要之一就是对 Windows 的反对, 明天,咱们很快乐的发表,咱们此次公布的 Flutter 稳定版中,曾经全面反对构建 Windows 桌面端应用程序了!Windows 与 Flutter几年前,咱们为 Flutter 制订了一个巨大的愿景,即从 iOS 和 Android 的挪动端利用上扩大到其余平台,其中就包含 Web 端和桌面端。 Flutter 的外围局部是跨平台的:从可移植的硬件加速的 Skia 图形渲染引擎,到 Flutter 的渲染零碎的外围单元,例如动画、主题、文本输出以及国际化,Flutter 提供了上百个 widgets。 ...

February 5, 2022 · 2 min · jiezi

关于flutter:Flutter-210-更新详解

Flutter 2.10 版已正式公布!尽管⾃ 上次稳固版本公布 以来还不到两个⽉,即便在这么短的工夫内,咱们也已解决和敞开了 1843 个 Issue,合并了来⾃寰球 155 位贡献者的 1525 个 PR。感激⼤家在 2021 年末的假期期间的出⾊⼯作。 咱们有⼏件令⼈兴奋的事件要发表,包含 Flutter 对 Windows ⽀持的重⼤更新、⼏项重⼤的性能改良、框架中图标和颜⾊的新⽀持以及一些⼯具改良等。此外,该版本还包含移除了 dev 渠道的更新、缩小对旧版 iOS 的⽀持以及几个简短的破坏性改变。让咱们开始吧! 应用 Flutter 构建 Windows 桌面利用反对曾经进入稳固阶段⾸先,Flutter 2.10 版本带来了稳固的 Windows ⽀持,无需再通过 --enable-windows-desktop 标记来独自配置 Windows 桌面版应用程序的反对,因为它当初曾经默认被启用! 当然,此次稳定版公布必定不只是“删掉”一个标记这么简略 ;-) 在 Flutter 2.10 的 Windows 反对中,也蕴含了对⽂本处理、键盘处理和键盘快捷键的⼴泛改良,以及间接与 Windows 集成的新形式、⽀持命令行参数、全球化⽂本输⼊和无障碍性能等。 无关 Windows 稳定版公布的更多信息,你能够浏览明天的另一篇推送文章,文章为大家详述了 Flutter 在 Windows 上的架构,同时阐明了有多少 Flutter package 和插件曾经⽀持 Windows。你还能够查看咱们的⼯具和应⽤合作伙伴在 Windows 上使⽤ Flutter 制作的一些⽰例等。 引擎的性能改良此版本的 Flutter 包含由社区成员 knopp 提供的 绘制脏区管理 的初步⽀持,他为 iOS/Metal 上的单个脏区域启⽤了选择性重绘。这一变动将一些基准测试中九非常位和九十九分位的光栅化工夫缩小了一个数量级,并将这些基准测试中的 GPU 利⽤率从 90% 以上升高到了 10% 以下。 ...

February 4, 2022 · 3 min · jiezi

关于flutter:回顾-Flutter-2021-重要时刻奉上虎年红包封面喜迎新年

2021 年,Flutter 正式进入 2.x 系列的正式版公布,年初的 Flutter 2 的公布 关上了一个新的“格局”,为 Flutter 的退出了第五大特色——「可移植性」,让 Flutter 从一个挪动框架正式“降级”为一个「可移植框架」,指标是让 Flutter 利用根本能够不加变动地在多种平台上运行。通过 Flutter,开发者们能够为任何平台创立好看、疾速且可移植的利用。3 月份,除了 Web 平台公布稳定版 之外,Flutter 也开始向桌面、可折叠和嵌入式设施上进行扩大。随之公布的 Dart 2.12 正式版 提供了健全的空平安和 FFI 的生产环境级反对。Dart 是一个站在 Flutter 背地的“秘密武器”,咱们提到的很多 Flutter 的“闪光点”,理论很大水平要归功于 Dart: 包含咱们熟知的有状态的热重载 (Stateful Hot-Reload),以及 Dart FFI 的成熟撑持了 Flutter 2 提到的「可移植性」,以及最新 Flutter 2.8 稳定版中对于性能的晋升的局部,都离不开 Dart。 21 年 5 月下旬的 I/O 大会仍是在线上举办,Flutter 2.2 和 Dart 2.13 稳定版正式公布。除了一直进化的 Web 反对,Flutter 也在挪动平台有了很多对于性能方面的改良,也着手从根底侧为 Flutter 加强扩大到其余平台进行改良。Flutter 2.2 着重改良开发体验,新我的项目会默认主动启用健全的空平安,Flutter 的开发者工具 (DevTools) 并和 IDE 插件都得以改良和更新,DartPad 也为教学者减少了疏导式代码体验。Dart 2.13 对空平安退出了更多更新,并推出了开发者们十分期待的「类型别名」的新个性。 ...

January 30, 2022 · 2 min · jiezi

关于flutter:Flutter实现左侧边栏导航

Flutter实现左侧边栏导航,点击左侧菜单右侧主动切换,左侧菜单能够实现主动居中,右侧滚动到底部持续滑可主动切换到下一页,上滑切换到上一页,左侧菜单追随切换,查看效果图: 下载地址:https://download.csdn.net/dow... 次要代码片段:wrapController.addListener(() { var maxScrollExtent = wrapController.position.maxScrollExtent; var pixels = wrapController.position.pixels; var dis = maxScrollExtent - pixels; // 滚动到顶部后再往上滚,主动跳到上一页 if (dis <= -100 && currentIndex < 30 - 1) { setState(() { currentIndex += 1; _scrollTo(currentIndex); }); wrapController.jumpTo(1); } // 滚动到底部后再往上滚,主动跳到下一页 if (dis >= maxScrollExtent + 100 && currentIndex > 0) { setState(() { currentIndex -= 1; _scrollTo(currentIndex); }); }});

January 29, 2022 · 1 min · jiezi

关于flutter:Flutter启动流程分析之插件化升级探索

Flutter是Google推出的一款跨平台框架。与Weex等其余跨端框架不同的是,Flutter的界面布局绘制是由本人实现的,而不是转换成对应平台的原生组件。那么各个平台是如何启动它的呢?从Flutter官网提供的架构图上看,Flutter Embedder层提供了底层操作系统到Flutter的程序入口,平台采纳适宜以后零碎个性的形式去各自实现。本文基于flutter 2.0.6版本源码,来摸索Android平台上flutter Embedder层对应的启动流程,看看这个过程中做了些什么事件,有什么问题是须要咱们在我的项目中留神的。 这部分源码位于engine源码中的/engine/shell/platform/android/ 目录下。 1.主流程先来看看整体的流程: Android以FlutterActivity/FlutterFragment/FlutterView的模式承载flutter界面。当咱们应用AndroidStudio创立一个新的flutter工程时,生成的MainActivity是间接继承了FlutterActivity,那么很显著,次要的逻辑都在这个FlutterActivity外面了。从流程图看到,flutter的启动流程也是从FlutterActivity的onCreate办法开始的: 1.FlutterActivity将onCreate次要的操作委托给delegate对象去实现。 2.delegate中调用setupFlutterEngine创立FlutterEngine。 3.FlutterEngine初始化各种channel之后,再创立FlutterLoader去加载资源文件和apk里的打包产物,之后初始化JNI的几个线程和DartVM。 4.delegate之后再通过FlutterEngine注册各个插件。 5.FlutterActivity调用delegate的onCreateView创立FlutterView。 6.最初,onStart生命周期中通过delegate的onStart办法执行DartExecutor.executeDartEntrypoint,这个办法会在jni层执行Dart代码的入口函数。至此启动实现。 1.1.FlutterActivityFlutterActivity也是继承的Activity,然而它把次要的性能都委托给了FlutterActivityAndFragmentDelegate类去实现,实现的Host接口次要是反对在delegate中获取FlutterActivity的一些参数,比方configureFlutterEngine,这些办法能够由子类去重写,实现自定义配置。 接下来,咱们看看FlutterActivity的onCreate(),次要的两个步骤是: 1.delegate.onAttach(this): 初始化FlutterEngine、注册各个插件。(留神,这里传的this即是delegate中的host对象) 2.setContentView(createFlutterView() ): 创立FlutterView并绑定到FlutterEngine。 这两个步骤都是委托给 FlutterActivityAndFragmentDelegate 去实现的。 1.2.FlutterActivityAndFragmentDelegate1.2.1.onAttach 总结一下,onAttach中次要做了一下几件事件: 1.设置flutterEngine: 1.1.判断是否从缓存中获取; 1.2.判断是否有自定义flutterEngine; 1.3.new 一个新的flutterEngine对象; 将插件attach到host activity,最终会调用各个插件的onAttachedToActivity办法。3.创立PlatformPlugin 4.注册插件。 1.2.2.configureFlutterEngine这里说一下configureFlutterEngine(flutterEngine)次要是干什么的,这个办法是在FlutterActivity中实现的,代码如下: 它通过反射找到了GeneratedPluginRegistrant类,并调用了其registerWith办法。这个类咱们能够在工程中的 /android/java/目录下找到,是flutter tool主动生成的,当咱们在pubspec.yaml中增加一个插件,并执行pub get命令后即会生成。 零碎默认应用反射实现,咱们也能够在MainActivity中重写这个办法,间接调用registerWith办法。 1.3.FlutterEngine再来看看FlutterEngine的构造函数。FlutterEngine是一个独立的flutter运行环境,通过它能应用DartExecutor执行Dart代码。 DartExecutor能够跟FlutterRenderer配合渲染UI,也能够在只在后盾运行Dart代码,不渲染UI。 当初始化第一个FlutterEngine时,DartVM会被创立,之后能够持续创立多个FlutterEngine, 每个FlutterEngine对应的DartExecutor执行在不同的DartIsolate中,但同一个Native过程只有一个DartVM。 能够看到,这外面做的事件还是很多的: 1.初始化AssetsManager。 2.创立DartExecutor并设置对应PlatformMessageHandler。 3.初始化一系列的零碎channel。 4.初始化FlutterLoader,加载Resource资源和libflutter.so、libapp.so等apk产物。 5.创立FlutterRenderer、FlutterEngineConnectionRegistry。 6.如果须要,主动注册pubspec.yaml中申明的插件。 接下来看一下FlutterLoader相干的内容。 1.4.FlutterLoaderFlutterLoader以单例的模式存在,一个过程只用初始化一次。用来加载apk安装包中的资源文件和代码产物,必须在主线程中进行。 startInitialization()办法中次要做了以下几件事件: 1.加载传给activity的meta配置信息; 2.提取apk安装包中的assets资源,次要是在DEBUG和JIT_RELEASE模式下的产物 ,比方vmSnapshotData、isolateSnapshotData等; 3.加载flutter engine C++局部源码,即在flutterJNI执行System.loadLibrary("flutter") ; ...

January 26, 2022 · 2 min · jiezi

关于flutter:使用-BLOC-模式构建你的-Flutter-项目

原文: 应用 BLOC 模式构建你的 Flutter 我的项目嗨伙计!我带着另一篇对于 Flutter 的全新文章回来了。这一次,将探讨和示范“如何构建 Flutter 我的项目”。这样你就能够轻松地保护、扩大和测试你的 Flutter 我的项目。在深入实际主题之前,我想分享一个小故事,对于为什么应该专一于为我的项目构建一个牢靠的架构。 更新:本文的 第 2 篇 和第 3 篇 已公布,对以后设计进行了一些更改,以解决一些问题并展现一些惊人的实现。 链接在这里。第 3 篇Compile time Dependency Injection in Flutter 第 4 篇Integration and Unit testing in Flutter 为什么须要结构化你的我的项目?“2015年,曾几何时,我过后是一名竞技程序员(Hackerearth 个人简介),同时也在学习 Android 利用程序开发。作为一名竞技程序员,我只关怀程序的输入和效率,素来没有思考过结构化我的程序和我的项目。这种趋势和编码格调也反映在我的 Android 我的项目中。我正在以一个竞技程序员的思维模式编写 Android 应用程序。一开始,所有都很好。因为只有我本人在我的项目上工作,没有老板给我提需要,不须要增加新性能或更改现有性能。然而,当我开始在一家初创公司工作并为他们构建 Android 应用程序时,我总是花很多工夫去批改程序中的现有性能。不仅如此,我甚者在构建应用程序的过程中引入了 Bugs。所有这些问题的根本原因是:‘我从来不遵循任何的架构模式,或者从未结构化我的我的项目’。随着工夫的流逝,我开始理解软件世界,并胜利的把我本人从一个竞技程序员转变成了一个软件工程师。现在,当启动一个新我的项目时,我的次要关注点是为我的项目构建一个松软的构造,或者架构。这帮忙我成为一名优良的、熟能生巧的软件工程师。” 完结我无聊的故事,让咱们回归本文的正题:“应用 BLOC 模式构建你的 Flutter 我的项目”。 咱们的指标构建一个非常简单的 app,有一个页面,页面内蕴含一个网格列表。列表项是从服务端获取的。列表的内容是The Movies DB站点中的热门电影。 Note: 在持续之前,你应该曾经理解 Widgets,how to make a network call in Flutter,并具备 Dart 相干常识的中级程度。本文有点长,并附带了大量其余资源的链接,不便你进一步浏览相干的主题。 让咱们开始表演吧. 在间接进入代码之前,先展现一下 BLOC 架构的视觉体验。咱们将遵循这个架构构建 app。 ...

January 25, 2022 · 5 min · jiezi

关于flutter:Flutter-BLoC-模式入门教程

原文:Getting Started with the BLoC Pattern 作者:Brian Kayfitz 理解如何应用风行的 BLoC 模式来构建 Flutter 应用程序,并应用 Dart streams 治理通过 Widgets 的数据流。设计应用程序的构造通常是利用程序开发中争执最强烈的话题之一。每个人仿佛都有他们最喜爱的、带有花哨首字母缩略词的架构模式。 iOS 和 Android 开发人员精通 Model-View-Controller(MVC),并将其作为构建应用程序的默认抉择。Model 和 View 是离开的,Controller 负责在它们之间发送信号。 然而, Flutter 带来了一种新的响应式格调,其与 MVC 并不齐全兼容。这个经典模式的一个变体曾经呈现在了 Flutter 社区 - 那就是 BLoC。 BLoC 代表 Business Logic Components。BLoC 的宗旨是 app 中的所有内容都应该体现为事件流:局部 widgets 发送事件;其余的 widgets 进行响应。BloC 位于两头,治理这些会话。Dart 甚至提供了解决流的语法,这些语法曾经融入到了语言中。 这种模式最好的中央是不须要导入任何插件,也不须要学习任何自定义语法。Flutter 自身曾经蕴含了你须要的所有货色。 在本教程里,你将创立一个 app,应用 Zomato 提供的 API 查找餐厅。在教程的结尾,这个 app 将实现上面的事件: 应用 BLoC 模式封装 API 调用搜寻餐厅并异步显示后果保护珍藏列表,并在多个页面展现筹备开始下载并应用你最喜爱的 IDE 关上 starter 我的项目工程。本教程将应用 Android Studio,如果你喜爱应用 Visual Studio Code 也齐全能够。确保在命令行或 IDE 提醒时运行 flutter packages get,以便下载最新版本的 http 包。 ...

January 24, 2022 · 9 min · jiezi

关于flutter:完全免费开源的Flutter到底有哪些优势该如何学习Flutter

什么是Flutter?Flutter是Google公司推出的新一代前端框架,最后指标只是为了满足挪动端跨平台的利用开发, 开发人员可应用 Flutter 在 iOS 和 Android 上疾速构建高质量的原生用户界面。但现在,Flutter 曾经 开始扩大为同时面向挪动端、Web、桌面端以及嵌入式设施开发利用了。Flutter 正在被越来越多的 开发人员和组织所应用,也是构建将来的 Google Fuchsia 利用的次要形式,并且它是完全免费、开源的。 Flutter的劣势:1、开源,也正是因为开源,所以在寰球开发者的疯狂反对下,这几年flutter飞速发展,越来越趋于欠缺,置信当前再windows,mac,linux等各个平台也能大放荣耀。真正做到一套代码多端部署。2、稳固,Flutter UI因为自绘UI,从而防止了平台层面的UI和系统升级导致的各种兼容问题。然而作为跨平台开发技术不可避免的须要去保护底层适配层和各种插件实现与原始平台的通信,这是所有跨平台的通病。3、高效,对开发者来说,应用 Flutter 开发利用非常高效。Flutter 广受好评的 Hot Reload 性能能够在 1 秒内实现代码到 UI 的更新,使得开发操作周期被大幅缩短。 Flutter独特性能:专一于可定制的小部件,能够应用Material Design和Cupertino包(而不是android XML)中的所有小部件集来轻松开发UI。热重载可帮忙开发人员立刻查看其更改。这缩小了开发工夫以及谬误修复工夫。一次写入,能够在任何平台上运行的任何代码,无需更改即可运行。Flutter应用Dart编程语言,该语言既能够提前应用,也能够及时进行编译,从而提供高性能和更快的启动工夫。原生ARM机器码可在Android和iOS上实现原生性能。装置Flutter您应该做的第一件事是获取SDK –软件开发工具包–它是一组软件工具,这些工具打包在一个软件包中,并且能够在您的开发环境中应用。 对于开发,咱们应用集成开发环境(IDE)–使您的开发和测试变得轻松快捷。如咱们之前所学,有2种风行的IDE – VS Code –它轻便,疾速,你想要IDE领有的性能它全都有 ! Android Studio –应用设施上的Android Studio,您只需装置Flutter和Dart的插件,设置SDK,就能够了。 设置很容易,您能够依照官网文档中的阐明进行操作。 应用Flutter构建一个简略的应用程序 让咱们构建一个简略的Hello World程序。通过此程序,咱们将理解Flutter的构造以及应用的次要办法。只管它很简略,但依然是一个良好的开始。 要想创立一个新的Flutter我的项目,只须要键入: $ flutter create flutter_appFlutter 新我的项目次要蕴含以下几个目录: flutter_appandroid –生成Android利用。任何对于Android的实现都将放在此文件夹中。 资产–用于存储数据文件,图像等… ios -生成的iOS利用。任何对于iOS的实现都将放在此文件夹中。 lib-次要代码文件都在这里创立,main.dart -主文件 test–用于单元测试 对于咱们这个比较简单的App,咱们仅须要“ main.dart”。文件。该文件自带一些代码,开发人员通常将其删除以从头开始编写代码。这正是咱们也将要做的! 首先重要的是导入“ material ”包。它用于引入UI组件。 import 'package:flutter/material.dart';就像许多其余语言一样,执行从main办法开始。main办法应包含runApp()办法,该办法调用要执行的代码。 void main() => runApp(new HelloWorldApp());要执行的代码不过是一个小部件。请记住,Flutter 是齐全基于 widget(小部件)的。 ...

January 21, 2022 · 1 min · jiezi

关于flutter:Android进阶Flutter-雷达扫描效果Flutter旋转扫描

效果图:1 .测试Demo启动文件 main() { runApp(MaterialApp( home: SignSwiperPage(), ));}class SignSwiperPage extends StatefulWidget { @override _SignSwiperPageState createState() => _SignSwiperPageState();}class _SignSwiperPageState extends State<SignSwiperPage> with SingleTickerProviderStateMixin {}接下来的代码都在 _SignSwiperPageState中编写 2 .动画控制器用来实现旋转 //动画控制器 AnimationController _animationController; @override void initState() { super.initState(); //创立 _animationController = new AnimationController( vsync: this, duration: Duration(milliseconds: 2000)); //增加到事件队列中 Future.delayed(Duration.zero, () { //动画反复执行 _animationController.repeat(); }); } @override void dispose() { //销毁 _animationController.dispose(); super.dispose(); }3 .旋转扫描成果 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Swiper Demo"), ), backgroundColor: Colors.white, //居中 body: Center( //层叠布局 child: Stack( children: [ //第一层的背景 圆形剪裁 ClipOval( child: Container( width: 200, height: 200, color: Colors.green, ), ), //第二层的扫描 buildRotationTransition(), ], ), ), ); }RotationTransition用来实现旋转动画 ...

January 21, 2022 · 1 min · jiezi

关于flutter:在-Flutter-中创建一个动画屏幕

原文https://medium.com/@baran.asl...代码https://github.com/ducafecat/... 参考https://pub.flutter-io.cn/pac...https://pub.flutter-io.cn/pac...https://pub.flutter-io.cn/pac...注释大家好,明天我要向大家展现如何在 Flutter 中创立一个动画屏幕,就像这样; 装置依赖项您能够从 pub.dev 取得依赖项 这些是我在我的我的项目中应用的版本: animated_text_kit: ^4.2.1simple_animations: ^3.1.1google_fonts: ^2.1.0在取得依赖关系之后,咱们在编码之前还有一个步骤。 有一个叫做 Liquid Studio 的应用程序是由 Felix Blaschke 创立的,这个应用程序生成飞镖代码来制作一些动画。 https://felixblaschke.github.... 当初是设计局部: 有许多选项和色彩抉择,为此我应用了默认设置和色彩。 当初,为了使它动画化,咱们须要增加另一个层称为 Plasma。 点击增加图层按钮并抉择 Plasma。 当初你能够自定义突变层和 plasma layers,我为本人做了一些定制。 当初要导出,点击左上角的导出按钮。 单击导出场景以导出所有图层。 当初咱们有了彩色动画的代码,咱们将在 IDE 中应用这段代码,但在此之前,让咱们先创立类构造。 让咱们创立一个有状态的小部件并首先返回一个 Scaffold。 当初,咱们心愿跳过动画页当咱们点击屏幕,要做到这一点,咱们能够应用 GestureDetector 小部件。 @override Widget build(BuildContext context) { return Scaffold( body: GestureDetector( ), ); }当初粘贴咱们在 liquid studio 中导出的代码,作为 GestureDetector 小部件的子部件。 @override Widget build(BuildContext context) { return Scaffold( body: GestureDetector( child: Container( decoration: BoxDecoration( gradient: LinearGradient( tileMode: TileMode.mirror, begin: Alignment.topRight, end: Alignment.bottomRight, colors: [ Color(0xfff44336), Color(0xff2196f3), ], stops: [ 0, 1, ], ), backgroundBlendMode: BlendMode.srcOver, ), PlasmaRenderer( type: PlasmaType.infinity, particles: 10, color: Color(0x442eaeaa), blur: 0.31, size: 1, speed: 1.86, offset: 0, blendMode: BlendMode.plus, particleType: ParticleType.atlas, variation1: 0, variation2: 0, variation3: 0, rotation: 0, ), ), ), ); }它应该看起来像这样,当初你会有一个谬误,这是因为咱们还没有导入简略的动画。 ...

January 20, 2022 · 2 min · jiezi

关于flutter:如何在-Flutter-创建一个后台任务

原文https://www.dltlabs.com/blog/...参考https://pub.dev/packages/back...注释明天,我将解释如何在 Flutter 创立一个后台任务。 在此之前,让咱们了解什么是后台任务。后台任务是在后盾运行的应用程序的辅助过程,即便应用程序没有运行或处于终止状态。 这一性能对于须要在后盾执行工作而不须要用户关上应用程序的应用程序来说是无益的ーー例如,每 15 分钟调用 api 获取数据。 让咱们在一个示例我的项目中实现一个后台任务,以便更好地了解这一操作的含意。 步骤:pubspec.yamlflutter pub add background_fetchflutter pub get在 main.dart 文件中导入后盾包,并注册 HeadlessTask,以便在应用程序终止后接管 backgroundFetch 事件。例如: void backgroundFetchHeadlessTask(HeadlessTask task) async {var taskId = task.taskId;if(taskId == ‘your_task_id’) {print(‘your_task_id’);print(‘[BackgroundFetch] Headless event received.’);_//TODO: perform tasks like — call api, DB and local notification etc…_}}void main() {runApp(MyApp());_//Registering backgroundFetch to receive events after app is terminated.// Requires {stopOnTerminate: false, enableHeadless: true}_BackgroundFetch._registerHeadlessTask_(backgroundFetchHeadlessTask);}这里咱们必须传递一个顶级函数。让咱们在 registerHeadlessTask 办法中给它命名为 call back dispatcher。而后咱们定义须要在后盾运行的工作: 配置 BackgroundFetchFuture<void> initPlatformState() async {_// Configure BackgroundFetch._var status = await BackgroundFetch._configure_(BackgroundFetchConfig(minimumFetchInterval: 15,forceAlarmManager: false,stopOnTerminate: false,startOnBoot: true,enableHeadless: true,requiresBatteryNotLow: false,requiresCharging: false,requiresStorageNotLow: false,requiresDeviceIdle: false,requiredNetworkType: NetworkType.NONE,), _onBackgroundFetch, _onBackgroundFetchTimeout);print(‘[BackgroundFetch] configure success: $status’);_// Schedule backgroundfetch for the 1st time it will execute with 1000ms delay.// where device must be powered (and delay will be throttled by the OS)._BackgroundFetch.scheduleTask(TaskConfig(taskId: “com.dltlabs.task”,delay: 1000,periodic: false,stopOnTerminate: false,enableHeadless: true));}调用 initState 中的 initPlatformState 办法并设置 BackgroundFetchConfig 类的配置。换句话说,在传递其余参数的同时,提供注册一次性工作或周期性工作的选项。 ...

January 20, 2022 · 2 min · jiezi

关于flutter:干货-Dart-并发机制详解

Dart 通过 async-await、isolate 以及一些异步类型概念 (例如 Future 和 Stream) 反对了并发代码编程。本篇文章会对 async-await、Future 和 Stream进行简略的介绍,而侧重点放在 isolate 的解说上。 在利用中,所有的 Dart 代码都在 isolate 中运行。每一个 Dart 的 isolate 都有独立的运行线程,它们无奈与其余 isolate 共享可变对象。在须要进行通信的场景里,isolate 会应用音讯机制。只管 Dart 的 isolate 模型设计是基于操作系统提供的过程和线程等更为底层的原语进行设计的,但在本篇文章中,咱们不对其具体实现展开讨论。 大部分 Dart 利用只会应用一个 isolate (即 主 isolate),同时你也能够创立更多的 isolate,从而在多个处理器内核上达成并行执行代码的目标。 多平台应用时留神 所有的 Dart 利用都能够应用 async-await、Future 和 Stream。而 isolate 仅针对 原生平台的应用 进行实现。应用 Dart 构建的网页利用能够 应用 Web Workers 实现类似的性能。 异步的类型和语法如果你曾经对 Future、Stream 和 async-await 比拟相熟了,能够间接跳到 isolate 局部进行浏览。 Future 和 Stream 类型Dart 语言和库通过 Future 和 Stream 对象,来提供会在以后调用的将来返回某些值的性能。以 JavaScript 中的 Promise 为例,在 Dart 中一个最终会返回 int 类型值的 promise,该当申明为 Future<int>;一个会继续返回一系列 int 类型值的 promise,该当申明为 Stream<int>。 ...

January 18, 2022 · 3 min · jiezi

关于flutter:Flutter-Convex-Bottom-底部导航

原文https://medium.flutterdevs.co...代码https://github.com/flutter-de... 参考https://pub.dev/packages/conv...注释 convex Bottom 底部条是一个应用程序 sketch 图,它的形态是 convex Bottom 的。它能够使用户界面看起来很棒,也能够改良用户与界面的交互方式。在本文中,咱们将建设一个简略的应用程序与最简略的模式之一,在 Flutter convex Bottom bar 目录:引言 增加依赖性 如何应用 性能 属性 施行 总结 GitHub 链接 简介:大家好,明天咱们要探讨的是一个十分重要的对于 Flutter UI 的话题,这个话题就是底层导航栏。在本文中,咱们理解了Convex Bottom Bar。Convex Bottom Bar是一种 Flutter 包装。Convex Bottom 的底部条是一个应用程序栏草图这样的形式,有一个 convex Bottom 状它。它能够使用户界面看起来很棒,也能够改良用户与界面的交互方式。在本文中,咱们将构建一个简略的应用程序与最简略的模式之一的Convex Bottom Bar。 查看列表 TabItems 小部件,您能够解释在 appbar 中显示的图标和它们的题目。列表应该只蕴含奇数的 TabItems 来运行小部件,而不会引起舛误。如果要显示图像或图标,能够为每个 TabItem 小部件中的图标变量提供图像。如果你想生成一个图标底部 appbar,你能够应用 ConvexButton.fab 小部件。它生成的参数更少,并且有一个疾速丑陋的单图标 appbar。 增加依赖项:在你的我的项目中去 pubspec。增加依赖项: 增加 https://pub.dev/packages/conv... 的最新版本。 dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 convex_bottom_bar: ^3.0.0咱们应用 convax_bottom_bar 来创立一个更好的 bootobar UI。 ...

January 13, 2022 · 2 min · jiezi

关于flutter:Flutter动态化框架Thresh

原文链接:满帮动态化Flutter框架“Thresh”,当初开源了 一、前言挪动端技术栈自诞生以来,其双端开发成本和公布效率始终广受诟病。为了解决这些问题,前端跨端技术始终在一直尝试,心愿能一次开发、多端运行并且能做到疾速公布。期间经验了多个技术倒退阶段。 第一阶段:以H5为代表,基于webview渲染 只需一次开发即可运行在双端,解决了开发效率低下的问题。然而webview存在重大的性能问题,用户的交互体验相比Native渲染有显著差距。 第二阶段:以RN和Weex为代表,前端技术栈开发,Native渲染 这些计划应用前端技术开发,最终映射到Native组件渲染,用户体验相比H5计划有了微小的晋升。然而这一阶段的计划同样存在有余。因为框架的渲染最终还是依赖双端Native组件,存在双端体验不一致性和平台兼容问题,极其状况下开发成本甚至超过双端Native开发。 第三阶段:Flutter,自绘引擎渲染 Google基于Skia渲染引擎,推出了Flutter跨平台框架,反对了Android/iOS/Web三个平台(尤其2.0的公布反对了全平台)。 基于自绘引擎,Flutter抹平了各个平台的差别,真正做到了一处开发,多端运行。业内对于Flutter彻底解决跨端开发的问题也寄予厚望。然而Flutter也并非完满,其动静能力有余,无奈像H5、RN等技术一样疾速公布。 为了解决动静能力有余的问题,满帮大前端团队从2019年开始对Flutter动态化能力进行摸索,自研了动态化Flutter框架,在外部一直优化迭代,已上线20+页面,包含外围页面订单详情、货主货源详情、导航地图等等,并且于2020年底进行了开源。 二、Flutter动态化的思考Thresh我的项目推出的初心是为了能提供一种基于Flutter的齐全跨端动态化计划,性能能达到甚至优于React Native,再加上其多端渲染一致性以及行将推出的Google Fuchsia零碎默认开发语言为Flutter,都表明Thresh将来将会充斥想象力。 2.1、动态化常见计划实现Flutter的动态化,通常须要思考以下几点: Flutter编译产物替换Google本来打算在2019年推出Code Push计划,起初放弃了,次要两个起因:违反利用商店的规定和平安方面思考;但目前android是能够通过产物替换来做到动态化,iOS端则无奈做到。 组件化搭建通过Dart来定义局部外围通用组件,在平台下发已有的组件列表拼装的页面JSON,端上再通过解析渲染成页面。这种计划能满足轻交互场景,但只能反对无限动态性。 自定义Dart转换+动静逻辑映射通过自定义一套Dart标准以及通过转换器生成JSON来做到动静更新,性能损失小,然而逻辑动态性须要提前预埋,且前端开发同学须要肯定的学习老本。 自定义DSL+依赖JS引擎的动静执行相似于RN/Weex,通过自定义动态化UI形容 + JS引擎的解释运行转换思路,最终构建成页面和执行动静逻辑。这个计划对于前端开发十分敌对,零学习老本,然而因为在JS引擎运行,会有一些性能损耗。 2.2、Thresh的抉择满帮的理论应用场景,业务疾速迭代,须要Android和iOS都要反对动态性,所以产物替换的思路不能齐全解决问题。随后又思考应用组件化思路,拼接多个业务组件尽管能搭建出页面,然而弊病也很显著,简单交互逻辑时无奈实现。另外自定义Dart形容UI计划尽管满足了动静更新的要求,然而逻辑动态性仍旧不强,而且Dart开发对于前端开发同学有肯定的学习老本。 最终,综合思考了开发效率、学习老本、多端性能和一致性等因素,咱们抉择了自定义JS形容UI + JS引擎的解释运行转换思路,类React语法结构,开发语言应用JS/TS。 三、实现原理3.1、构建Dart页面原理在 Flutter 中形容视图组成的根本单位是 Widget,每一个 Widget 只蕴含以后部件的配置信息,它是一个轻量的、可被高效创立并销毁的数据结构。而许许多多的 Widgets 组合在一起,构建出了一个蕴含视图所有信息的 WidgetTree。之后 Flutter 会从 WidgetTree 中生成 ElementTree,再由 ElementTree 生成 RenderObjectTree。ElementTree 中的 Element 会同时持有其对应的 Widget 与 renderObject。 三棵树中,WidgetTree 会被频繁创立于销毁,然而 ElementTree 和 RenderObjectTree 只会在产生状态扭转的时候才会扭转,ElementTree 负责元素的更新与 diff,RenderObjectTree 则负责理论的布局与绘制。 外围思路是把 Flutter 的页面渲染逻辑中的三棵树中的第一棵树Widget,通过JS 来结构。这其中要实现JS与 Flutter 层实现根底组件映射,再通过JS引擎来生成UI形容,并传递给Dart层的 UIEngine,UIEngine 把UI形容转换为 Flutter 控件,最终渲染成页面。 Thresh框架实现了罕用根底组件的定义与开发,能撑持95%以上业务场景的接入,语法定义规定反对React,对前端开发人员零老本接入。现反对的组件列表以及其局部属性如下 3.1.1、Flutter初始化Flutter 是由 main() 函数开始程序执行的,次要实现以下几个工作: ...

January 13, 2022 · 3 min · jiezi

关于flutter:基于-Riverpod-的-Flutter-状态管理

原文https://itnext.io/flutter-sta...代码https://github.com/iisprey/ri... 参考https://itnext.io/a-minimalis...https://pub.dev/packages/stat...https://iisprey.medium.com/ge...https://iisprey.medium.com/ho...注释 正如我上周所承诺的,我将向您展现我本人的最终国家治理解决方案门路 Riverpod + StateNotifier + Hooks + FreezedRiverpod 太棒了!然而好的例子并不多。只有最根本的,就这样。这一次,我试图使一个例子既可了解又简单。我的目标是通过这个例子教你什么时候应用 Riverpod,以及如何应用它。只管我简化了过程。心愿你喜爱! 动机 在这个例子中咱们要做什么?咱们只须要从 API 中获取一些数据,而后在 UI 中对它们进行排序和过滤 基本上,咱们会;Create simple and complex providers and combine them创立简略和简单的提供程序并将它们组合起来Use AsyncValue object and show async value in the UI using when method应用 AsyncValue 对象并在 UI 中应用 when 办法显示 async 值Also, create freezed objects for immutable object solution同时,为不可变物件/解决方案创立解冻对象咱们开始吧! 创立 API 服务留神: 我没有找到一个好的 API 模型来应用过滤性能,因为我本人增加了这些角色。原谅我这么说final userService = Provider((ref) => UserService());class UserService { final _dio = Dio(BaseOptions(baseUrl: 'https://reqres.in/api/')); Future<List<User>> getUsers() async { final res = await _dio.get('users'); final List list = res.data['data']; // API didn't have user roles I just added by hand (it looks ugly but never mind) list[0]['role'] = 'normal'; list[1]['role'] = 'normal'; list[2]['role'] = 'normal'; list[3]['role'] = 'admin'; list[4]['role'] = 'admin'; list[5]['role'] = 'normal'; return list.map((e) => User.fromJson(e)).toList(); }}应用 freezed 和 json_serializable 创立不可变模型咱们只须要创立一个 ...

January 12, 2022 · 3 min · jiezi

关于flutter:Flutter-2022-产品路线图发布

为了晋升产品的透明性,每年年初 Flutter 团队都会公布今年度的产品路线图,以帮忙应用 Flutter 的团队和开发者们依据这些优先事项制订打算。 2022 年 Flutter 团队将重点通过关注以下几个畛域和方向针对产品进行研发和改良,包含开发者体验、桌面端、Web 端、框架和引擎、Dart 编程语言、卡顿,并打算于往年进行对 32 位 iOS 设施的反对,并减少对软件供应链平安方面的投入,以达到 SLSA 4 级 (用户能够高度确信该软件没有被篡改)。 重点关注开发者体验作为一款面向开发者的工具,咱们最关注的就是开发者体验。咱们的指标是创立一款开发者们酷爱的 SDK,这将会在很多方面有所体现。包含创立实现通用业务场景的 widget、厘清现有的 API 并引入新的 API 以更便捷的形式实现常见的设计模式、改善错误信息提醒、改良开发者工具和 IDE 插件、创立新的 Lint 规定、修复框架和引擎的 bug、改良 API 文档、创立更有用的示例代码,以及在 Web 上实现热重载 (Hot Reload) 和改良 Dart-to-JS 场景的堆栈跟踪等。 桌面端2022 年咱们打算将 Flutter 的桌面端反对推动到稳固版本。咱们会把重点放在测试上,并在平台可用之后进行颁布——首先是 Windows 平台,而后是 Linux 平台,而后是 macOS 平台。这项工作的重要局部是扩增回归测试套件,以让咱们有充沛的信念将 Flutter 带到桌面端平台而无需毁坏现有的代码。 跟踪 Windows 平台进度: https://github.com/flutter/flutter/projects/209跟踪 Linux 平台进度: https://github.com/flutter/flutter/projects/216跟踪 macOS 平台进度: https://github.com/flutter/flutter/projects/215Web 端2022 年咱们打算晋升 Flutter Web 的性能、插件品质、无障碍个性和多浏览器一致性的体验,与此同时,咱们也在打算让 Flutter 利用更不便的嵌入其余页面。 ...

January 12, 2022 · 1 min · jiezi

关于flutter:用React写flutter-app

豆皮粉儿们,大家好呀,明天这一期,由字节跳动数据平台的“奕轩”同学给大家带来如何用React写flutter app。 作者:奕轩基本概念flutter谷歌推出的挪动端框架,特点是多端高度一致性,性能好,蕴含丰盛的安卓和ios格调的组件,应用dart作为开发语言 长这样⬇️ mxflutter一句话:让js以dart和flutter的模式写app 长这样⬇️ https://github.com/mxflutter/... react react架构 援用自Remax - 应用真正的 React 构建小程序 关键点ReactReconciler保护VirtualDOM,fiber算法,决定VirtualDOM的所有更新VirtualDOM的渲染由各个renderer实现:react-dom、react-nativeComponent组件宿主组件宿主能了解的最小单位的组件,浏览器中是div,span,h1等,react-native中是View,Text,Image等,宿主元素是一个字符串 复合组件用宿主组件或其余复合组件组成的组件,是一个class component或function component Element应用React.createElement创立的对象,用来形容视图节点,能够了解为组件的实例长这样⬇️ 实现根本思维定义一种虚构节点类VNode,并定义VNode的append、remove、insert等办法,利用react-reconciler提供的api在创立节点、插入节点、更新节点等接口中对VNode进行更新。这样,在ReactReconciler每次对VirtualDOM更新时咱们都能晓得更新了什么,并且把更新的内容转成咱们意识的构造,保护一个VNode tree,用它渲染widget tree 具体过程初始代码⬇️ React.createElement ⬇️ ReactReconciler+VNode=NodeTree ⬇️ 递归渲染⬇️ 外围上述过程最要害的在于如何将一个react element tree转换为咱们可能进行递归的节点树 流程图 react-reconcilerreact-reconciler 能够认为是一组hooks(相似于 git hooks,而非 react hooks),去填充它裸露进去的这些生命周期函数,就能够将 React 利用到任意“宿主”零碎中 长这样⬇️ react-reconciler做了什么? 在首次渲染过程中构建出vDOM tree,后续须要更新时(setState()),diff VirtualDOM tree失去 change,并把node change更新(patch)到NodeTree VNodeVNode是VirtualDOM的最小单位,在react-reconciler的hook办法中去创立VNode、插入子VNode、删除子VNode等 长这样⬇️ BridgeBridge的作用是桥接ReactReconciler和mxflutter,当VNode有更新时,VNode持有的Bridge将diff node更新到mxflutter 将来咱们的指标是现有我的项目能够通过越少越好的批改能跑在app上, 上述原理只解决了dom映射的问题,还有以下问题须要被解决 DOM:还须要反对selectorBOM:编译时替换为app框架上的对象第三方包:初步构想是各平台保护本人的包,或应用web-component事件处理:还没想好The End

January 11, 2022 · 1 min · jiezi

关于flutter:Flutter实现电影院选座效果

导语接到了一个仿电影院的需要,上周简直是找遍了百度,谷歌,stackoverflow。均没有找到用flutter实现的成果,那只能本人写一个了。本文只讲思路,具体实现还需各位看官本人入手。只有看懂了上面的思路,实现起来非常简单。 间接上效果图竖屏: 横屏: 初始化自适应屏幕的放大放大成果: 布局剖析两头的座位=>矩阵,通过Column嵌套Row实现,不能通过GridView实现(滑动抵触,下文会阐明) 左侧导航条=>一个简略的Column(不能用ListView,同样会造成滑动抵触) 交互剖析&实现放大放大拖动成果: 对于放大放大拖动的成果,Flutter当初有自带的组件InteractiveViewer通过这个组件可完满实现放大放大成果。组件属性这边不开展解释,比较简单,可点击下面链接自行理解。 这里讲下两个重点属性: 1、回调事件 交互开始 onInteractionStart交互更新 onInteractionUpdate交互完结 onInteractionEnd2、变换控制器transformationController 能够通过这个类来通过代码管制放大放大成果 导航条追随座位表放大放大拖动:右边导航条追随两头座位的放大放大,以及行数定位不偏离:下面讲的那些货色个别大家都能想到,也很好实现。这个交互成果的真正难点是这个追随滑动成果。 因为右边的导航条是固定在最左侧的,而座位表能够全屏拖动,所以这座位表和导航条不能放在一个缩放组件里, 不然座位表放大的时候,间接将导航条放大出屏幕了。所以咱们的思路就是将导航条和座位表作为Stack的子组件,而后座位表实现放大放大成果,并且让导航条能追随座位表进行放大放大。笔者在这试了很多办法: 办法一:左侧导航栏和两头座位表均应用InteractiveViewer 而后通过InteractiveViewer的回调事件和变换控器来实现成果同步 后果: 失败,transformationController的原理是Matrix4泛型的ValueNotifier(四维矩阵),简略的挪动放大还能实现,齐全克隆一个放大放大拖动成果,笔者做不到。。各位如果线性代数十分牛逼的能够试试。 办法二:flutter有一个同步滚动组件叫linked_scroll_controller 他能将两个scrollController绑定在一起,实现同步滚动。 所以让左侧导航栏应用ListView,两头座位表应用InteractiveViewer嵌套GridView, 而后将ListView和GridView的ScrollController绑定在一起实现同步滚动。 后果: 失败,InteractiveViewer的滑动是通过Matrix4实现的,和ListView的滑动抵触。 同步滚动实现了,然而放大放大的拖动无奈执行。 办法三:应用InteractiveViewer是逃不过的,不然本人实现放大放大成果太头疼, 如果能像下面的linked_scroll_controller一样,将InteractiveViewer的缩放成果复制到另外一个InteractiveViewer中去,那就完满了。 就是办法一的思路,然而用InteractiveViewer凋谢的接口和控制器,无奈实现,这个时候就须要去浏览了解InteractiveViewer的源码,看看有没有什么启发。 @override  Widget build(BuildContext context) {    Widget child = Transform(      transform: _transformationController.value,      child: KeyedSubtree(        key: _childKey,        child: widget.child,      ),    );    if (!widget.constrained) {      child = OverflowBox(        alignment: Alignment.topLeft,        minWidth: 0.0,        minHeight: 0.0,        maxWidth: double.infinity,        maxHeight: double.infinity,        // maxHeight: 220.w,        child: child,      );    }    if (widget.clipBehavior != Clip.none) {      child = ClipRRect(        clipBehavior: widget.clipBehavior,        child: child,      );    }    // A GestureDetector allows the detection of panning and zooming gestures on    // the child.    return Listener(      key: _parentKey,      onPointerSignal: _receivedPointerSignal,      child: GestureDetector(        behavior: HitTestBehavior.opaque,        // Necessary when panning off screen.        dragStartBehavior: DragStartBehavior.start,        onScaleEnd: onScaleEnd,        onScaleStart: onScaleStart,        onScaleUpdate: onScaleUpdate,        child: child,      ),    );  }不看不晓得,一看吓一跳,其实InteractiveViewer曾经将所有的办法都替咱们封装好了。 留神下面的GestureDetector,整个InteractiveViewer的手势交互办法,其实就是onScaleEnd,onScaleStart,onScaleUpdate这三个办法。 那咱们只须要将座位表组件回调的的这三个办法中的参数,传入到导航条组件中去就行,而后删掉导航条组件的GestureDetector,让导航条组件只承受来自座位表组件的手势交互参数。 咱们只需重写两个InteractiveViewer,一个为主组件(座位表),一个为从组件(导航条),并凋谢InteractiveViewerState,当座位表组件回调手势的三个办法时,通过key将三个办法的参数传入导航条组件就OK。 _onInteractionUpdate(ScaleUpdateDetails details) {    if (controller.fromInteractiveViewKey.currentState != null) {      controller.fromInteractiveViewKey.currentState.onScaleUpdate(details);    }  }  _onInteractionStart(ScaleStartDetails details) {    if (controller.fromInteractiveViewKey.currentState != null) {      controller.fromInteractiveViewKey.currentState.onScaleStart(details);    }  }  _onInteractionEnd(ScaleEndDetails details) {    if (controller.fromInteractiveViewKey.currentState != null) {      controller.fromInteractiveViewKey.currentState.onScaleEnd(details);    }  }齐全无需任何加工,将参数照搬照抄的传入导航条组件。咱们就能实现同步缩放拖动的成果! 这里必须特地留神:座位表和导航条组件的单个item的高度必须完全相同,包含margin,padding,不然还是会呈现错位景象至此,最大的难点同步缩放和滑动就解决了。 底部弹框悬浮在座位表上方:点击座位后弹出底部弹框,遮蔽局部座位表,然而座位表能继续向上拖动显示完最初一行的数据这个乍一看没啥难的,但细细一想也有点简单。首先, 明确座位表的显示区域是蕴含底部弹框的,因为底部弹框是悬浮在座位表下面的,那么咱们就只能应用margin而不是padding,所以依据设计图底部弹框的height,咱们将marginBottom设成这个height就行,然而会有个问题: 当整个座位表放大margin局部也会同步放大,这样就会导致放的越大,座位表间隔上面空出的间距就越大。 解决思路: 咱们须要拿到以后放大的倍数,动静调整margin, 以后放大X倍,原始margin为Y,则以后放大后的margin=Y/X,Y已知,咱们只须要晓得X就行。然而在_onInteractionUpdate接口中,X并非以后放大几倍,而是较上次缩放后的缩放倍数。即: 初始1.0倍。第一次放大至2倍,接口回调的放大倍数为2第二次放大至3倍,接口回调的放大倍数为1.5(较第一次又放大了1.5倍)。并且更重大的是当放大到maxScale后,接口仍会继续回调放大倍数。这就很困扰咱们,起初浏览源码后发现,咱们所要的较原始放大倍数的以后放大倍数参数在InteractiveViewer类中的。 // Return a new matrix representing the given matrix after applying the given  // scale.  Matrix4 _matrixScale(Matrix4 matrix, double scale) {    if (scale == 1.0) {      return matrix.clone();    }    assert(scale != 0.0);    // Don't allow a scale that results in an overall scale beyond min/max    // scale.    final double currentScale =        _transformationController.value.getMaxScaleOnAxis();    final double totalScale =currentScale * scale;    //改了算法    // final double totalScale = math.max(    //   currentScale * scale,    //   // Ensure that the scale cannot make the child so big that it can't fit    //   // inside the boundaries (in either direction).    //   math.max(    //     _viewport.width / _boundaryRect.width,    //     _viewport.height / _boundaryRect.height,    //   ),    // );    final double clampedTotalScale = totalScale.clamp(      widget.minScale,      widget.maxScale,    );    widget.scaleCallback?.call(clampedTotalScale);    final double clampedScale = clampedTotalScale / currentScale;    return matrix.clone()..scale(clampedScale);  }留神下面的scaleCallback,这是笔者本人实现的回调办法,其中的clampedTotalScale就是咱们想要的较初始缩放倍数的以后放大倍数, 即:初始1.0倍,第一次放大至2倍,接口回调的放大倍数为2,第二次放大至3倍,接口回调的放大倍数为3(较初始放大了3倍)。 且clampedTotalScale永远在minScale和maxScale的区间内。拿来即用十分不便。 下面代码中有一段算法被我正文掉了,这段代码的成果是: 当InteractiveViewer中的child曾经齐全显示的时候,则无奈再放大,即minScale不仅仅取决于咱们设置的值,还取决于InteractiveViewer的child显示成果,这里我不须要这个限度,则将他正文掉了。 其实如果要完满实现UI给出的成果,有很多中央要用到margin,比方座位表的上下左右margin,只有拿到了下面的clampedTotalScale,均能够动静计算,很不便。 横竖屏适配成果下面的gif图有横屏成果,横竖屏切换用的也是官网API,OrientationBuilder,这个用起来也很简略。这里讲一个UI适配的注意事项: 因为笔者我的项目用了ScreenUtil(UI自适应),所以在竖屏的时候,传入竖屏的UI尺寸图,且尺寸结尾应用.w进行适配,当横屏时,传入横屏的UI尺寸图(其实就是将竖屏的width和height倒置),而后尺寸结尾应用.h进行适配。这样就根本能完满适配横竖屏,残余的细节就能够微调。 初始放大倍数如下面的效果图, 在第一次进入或横竖屏切换时,当座位表布局过多(默认显示不下时),尽可能放大以显示更多的内容(上限放大至minScale),当座位表布局过少(默认显示时屏幕很空),尽可能放大直至显示满屏幕(下限放大至maxScale)。 下面成果可总结为:在尽可能显示齐全的前提下尽可能大。 InteractiveViewer并没有初始放大倍数参数,默认进入都是放大1.0倍。这里就须要咱们本人来算出这个初始放大倍数。 计算如果有用screenUtil,以下计算留神辨别横竖屏,横屏时适配结尾用.w,竖屏用.h,其中异形屏的padding不必辨别横竖屏,零碎会主动更改 1、整个座位表的显示区域:屏幕高-异形屏高低padding-竖屏时底部悬浮框的height(横屏悬浮框如果不在底部,则为0)-标题栏高度以及本人加的一些其余布局的高度。屏幕宽-异形屏左右padding-横屏时右侧悬浮框width(竖屏时悬浮框如不在右侧,则为0)- 导航条宽度(这个导航栏宽度也须要依据放大放大倍数动静计算)-其余本人加的布局宽。 2、计算初始放大倍数(1.0)下的座位表item的width和height以及padding,这个间接按设计图的就行。3、取得以后座位表的x轴和y轴。即每行几个座位,一共有几行座位。4、计算假如要将所有座位表显示下,每个item的width和height。即用下面1.所得的座位表显示区域的宽高别离除以座位表的x和y, 5、将2.的width除以4.width,即如X轴齐全显示下须要缩放的值SX,将2.的height除以4.height,即如Y轴齐全显示下须要缩放的值SY, 6、比拟SX和SY两值,取小值defaultS(在尽可能显示齐全的前提下尽可能大)7、如果defaultS在minScale和maxScale区间内,则取defaultS,反之取区间边界值。缩放用transformationController将InteractiveViewer缩放到defaultS // 座位表mainTransformationController.value = Matrix4.identity()..scale(defaultS);// 导航条fromTransformationController.value = Matrix4.identity()..scale(defaultS);这里留神座位表和导航条都要进行缩放。 缩放动静margin最初别忘记将各种须要动静计算的margin也缩放到defaultS值。 如果有横竖屏切换成果的,在每次横竖屏切换的时候都动静计算初始放大值,须要留神,每次计算的时候都要将动静计算的margin置为初始值(即当缩放大小为1.0时的margin值)。 有时候想不进去就看源码,立马就会醍醐灌顶。 Android高级开发零碎进阶笔记、最新面试温习笔记PDF,我的GitHub ...

January 11, 2022 · 1 min · jiezi

关于flutter:2022年为什么要使用Flutter构建应用程序

2022年为什么要应用Flutter构建应用程序?作者:坚果 公众号:"大前端之旅" 华为云享专家,InfoQ签约作者,阿里云专家博主,51CTO博客首席体验官,开源我的项目GVA成员之一,专一于大前端技术的分享,包含Flutter,小程序,安卓,VUE,JavaScript。 明天每个人都想构建一个应用程序,然而谁又能嗔怪他们呢?事实上,现在每个人都领有智能手机,它已迅速成为咱们白天最常应用的工具。当咱们没有它们时,咱们会感到短少一些货色,咱们甚至把它们带到洗手间,咱们甚至想不出没有它们,如何出门。无论咱们喜爱与否,它对咱们生存都在进行最快,最踊跃的影响,而这要归功于应用程序。 利用有一种非凡的形式来吸引用户,而其余事物则没有。这里给大家顺便带一下,我之前写过的一篇文章你想好,如何为你的利用做推广了吗?这可能是因为其丑陋的用户界面,通过三思而行的用户体验或完满的可用性。这就是为什么编程能够被认为是一门艺术的全副起因,而Flutter在这里为咱们提供了这条路线。 什么是Flutter?"Flutter是Google的UI工具包,用于从单个代码库为挪动,Web和桌面构建好看,能够的应用程序。Flutter是一个跨平台框架,使开发人员可能从单个代码库在不同的平台上编程。这为桌面带来了很多劣势。 以下是对于Flutter的一些最特点: 它是开源的它有一个清晰的文档和一个平凡的社区由谷歌开发它有一个适宜所有的小部件进步开发人员的工作效率一个繁多的代码库来统治它们.png) 为什么跨平台如此重要?跨平台开发容许创立与多个操作系统兼容的软件应用程序。通过这种形式,该技术克服了为每个平台构建惟一代码的原始开发艰难。 当然,明天开发一个应用程序意味着呈现在两个相干操作系统上:Android和iOS。在过来,这意味着领有两个代码,两个团队和两倍的老本。多亏了跨平台,咱们能够让一个团队从一个代码库为多个平台创立一个应用程序。 毫无疑问,Flutter并不是惟一的跨平台解决方案,咱们能够持续探讨其他人如何尝试采取不同的方向,但这是另一篇文章。然而,有一件事是必定的,那就是:跨平台将持续存在。这也是2022年为什么要学习Flutter的理由 单个代码库,单个技术栈。为了持续我要去的中央,如果管理应用程序的开发是艰难的,设想一下治理两种不同技术的开发。每个更改都必须在两种不同的技术中编码和批准。团队必须分为两个,iOS团队和Android团队。这就是为什么让一个团队在单个代码库中工作更无益的起因。 Flutter 善于的中央*任何软件开发人员都相熟这个概念,因为咱们做出的每一个抉择都决定了长处和毛病。因而,再次抉择Flutter在您的我的项目中有利有弊。 在本文中,我想提供无关它的信息,以便在适宜您的我的项目时进行衡量。以下是它的一些益处: 缩短上市工夫Flutter 是一项杰出的原型设计技术 - 不仅是 MVP ,还包含具备理论产品性能的应用程序。通过应用Flutter,您将为两个平台(iOS和Android)构建一个应用程序,这能够大大减少开发工夫,从而能够更快地将您推向市场。此外,基本上将小部件用于所有内容的可能性以及具备大量可用库的可能性是加快速度的另一个重要因素。 单个开发团队通过应用Flutter,你能够领有一个开发团队,而不须要有两个iOS和Android专家团队。您不用放心同步两台计算机,两个代码库,您能够简略地同时在两个平台上公布。 升高开发成本领有一个开发团队还有其余益处,例如大大降低老本。这对任何想要构建应用程序的人来说都十分有吸引力,因为进入应用程序市场的经济门槛较低。使其具备老本效益 然而等等,下面说了这么多益处,有什么不利吗 什么时候应用Flutter不不便?当然,在某些状况下,Flutter并不齐全适宜您的我的项目。当这种状况产生时,咱们必须简略地承受它,并抉择原生开发或其余抉择。 例如,如果你的利用须要并且齐全依赖于某些特定的硬件设施密集型性能,你可能想要找出是否存在某种Flutter插件。然而,因为它十分新,我强烈建议您进行概念验证,需要剖析,以升高技术不是阻碍的危险。 此外,还有一些Flutter尚未达到的中央,例如加强事实和3D游戏。在这些状况下,Unity 可能更适宜您的我的项目。请记住,您始终能够尽可能应用 Flutter,而后对于特定的事件应用 native 或 Unity。请记住,将 Flutter 与原生集成始终是一个可用的选项。 想学习另一个技术?如果你对学习另一种技术有想法,我明确了。然而,请在这里持续等我,让我向您展现它到目前为止是如何演变的: Flutter的测试版于2018年3月推出,并于2018年12月首次上线。从那时起,Flutter巩固了其在市场上的位置,并持续高速崛起。 Flutter社区也在一直倒退。Flutter受到大型市场参与者和顶级公司的信赖,如Google Ads,丰田,还有国内的很多大厂等等。, 对于这点你能够去查看你的手机的应用程序,置信会发现很多对于Flutter的形迹。 最初: 自信地迁徙到 Flutter能够必定地说,Flutter 有着光明的将来。所以,如果你始终生存在一块石头下并且还没有据说过它,当初就去看看。这是官网https://flutter.dev/ 就我的应用来说,Flutter 不仅达到了我的冀望,而且超出了我的冀望。这无疑是一项咱们从头到尾都爱上的技术。它使咱们可能在创纪录的工夫内高效地构建应用程序。 这就是我信赖 Flutter 的起因。我置信它的将来。我也违心为此推广Flutter。 在接下来的笔记中,我将揭开 Flutter 的神秘面纱,并分享一些机密的利用程序开发技巧,敬请期待,我是坚果,我有一个公众号“大前端之旅”,欢送关注!

January 11, 2022 · 1 min · jiezi

关于flutter:Flutter值得学吗未来还能走多远

什么是Flutter?Flutter是谷歌的挪动UI框架,能够疾速在iOS和Android上构建高质量的原生用户界面。Flutter能够与现有的代码一起工作。在全世界,Flutter正在被越来越多的开发者和组织应用,并且Flutter是完全免费、开源的。简略来说,Flutter是一款挪动应用程序SDK,蕴含框架、控件和一些工具,能够用一套代码同时构建Android和iOS利用,并且性能能够达到原生利用一样的性能。 Flutter的劣势:1、开源,也正是因为开源,所以在寰球开发者的疯狂反对下,这几年flutter飞速发展,越来越趋于欠缺,置信当前再windows,mac,linux等各个平台也能大放荣耀。真正做到一套代码多端部署。2、稳固,Flutter UI因为自绘UI,从而防止了平台层面的UI和系统升级导致的各种兼容问题。然而作为跨平台开发技术不可避免的须要去保护底层适配层和各种插件实现与原始平台的通信,这是所有跨平台的通病。3、高效,对开发者来说,应用 Flutter 开发利用非常高效。Flutter 广受好评的 Hot Reload 性能能够在 1 秒内实现代码到 UI 的更新,使得开发操作周期被大幅缩短。 Flutter利用通过LibChecker app能够轻易关上自己手机所装置的 app(参考了 GSY 办法),抉择查看哪些 app 蕴含了 Flutter: 发现了没有,简直大厂的 App都在列: 微信淘宝、天猫、UC、菜鸟、饿了么度小满、百度贴吧网易有道词典...这些 App 正在尝试甚至曾经大规模应用Flutter。 Flutter找工作的加分项 Flutter目前也是Android开发岗位的加分项,通过上图咱们能够看出,很多大厂在高薪招聘这方面的人才。 怎么学 Flutter ?这份谷歌开源的《Flutter残缺开发实战详解》,心愿能够帮忙大家用最短时间学习Flutter。教程通俗易懂,实例丰盛,既有基础知识,也有进阶技能,可能帮忙读门者疾速入进阶,快珍藏起来!!!一、Dart语⾔和Flutter根底 ⼆、 疾速开发实战篇1、根底控件2、数据模块3、其余性能 三、 打包与填坑篇1、打包2、细节3、问题解决 四、 Redux、主题、国际化1、Redux2、主题3、国际化 五、 深⼊摸索1、WidgetsFlutterBinding2、InheritedWidget3、内存4、线程5、热更新 六、 深⼊Widget原理 七、 深⼊布局原理1、单⼦元素布局2、多⼦元素布局3、多⼦元素滑动布局 ⼋、 实⽤技巧与填坑 九、 深⼊绘制原理1、绘制过程2、Slider 控件的绘制实现 ⼗、 深⼊图⽚加载流程1、图⽚流程2、本地图⽚缓存3、其余补充 ⼗⼀、全⾯深⼊了解Stream1、Stream 由浅⼊深2、StreamBuilder3、rxdart ⼗⼆、全⾯深⼊了解状态治理设计1、scoped_model2、BloC3、flutter_redux4、fish_redux ⼗三、全⾯深⼊触摸和滑动原理 ⼗四、混合开发打包 Android 篇1、前⾔2、打包3、插件4、堆栈 Flutter ⾯试知识点集锦Dart 局部Flutter 局部 Flutter 开发实战与前景瞻望 - RTC Dev Meetup1、挪动开发的现状2、Flutter 实战3、混合开发4、PlatformView ...

January 10, 2022 · 1 min · jiezi

关于flutter:Flutter混合开发之FlutterFragment使用

咱们晓得,原生Android集成Flutter次要有两种形式,一种是创立flutter module,而后以原生module那样依赖;另一种形式是将flutter module打包成aar,而后在原生工程中依赖aar包,官网举荐aar的形式接入。 如何在原生Android工程中以aar的形式接入Flutter,大家能够参考我之前文章的介绍:原生Android工程接入Flutter aar。明天想给大家分享的是FlutterFragment的应用。 一、Android原生工程在Android原生开发中,实现底部Tab导航通常有3种形式,别离是: RadioGroup + ViewPager + Fragment:可能预加载相邻的FragmentFragmentTabHost + Fragment:加载选中的FragmentBottomNavigationView:有选中动画成果此处,咱们应用BottomNavigationView来实现底部Tab导航。首先,咱们新建一个Android原生工程,而后再新建三个 Fragment 。activity_main.xml布局代码如下: <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingTop="?attr/actionBarSize"> <FrameLayout android:id="@+id/fl_container" android:layout_width="match_parent" android:layout_height="0dp" app:layout_constraintBottom_toTopOf="@id/bottom_navigation" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" /> <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="0dp" android:layout_marginEnd="0dp" android:background="?android:attr/windowBackground" app:itemTextColor="@color/tab_text_color" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:menu="@menu/bottom_nav_menu" /></androidx.constraintlayout.widget.ConstraintLayout>代码中引入了一个bottom_nav_menu.xml布局,代码如下: <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/nav_home" android:icon="@drawable/tab_home" android:title="@string/tab_home" /> <item android:id="@+id/nav_car" android:icon="@drawable/tab_car" android:title="@string/tab_car" /> <item android:id="@+id/nav_me" android:icon="@drawable/tab_mine" android:title="@string/tab_me" /></menu>其中,BottomNavigationView罕用的属性如下: app:iteamBackground:指的是底部导航栏的背景色彩,默认是主题的色彩app:menu:指的是底部菜单(文字和图片都写在这个外面,举荐图片应用矢量图)app:itemTextColor:指的是导航栏文字的色彩app:itemIconTint:指的是导航栏中图片的色彩最初,在MainActivity.java中实现Tab的切换,代码如下: class MainActivity : AppCompatActivity() { private var fragments = mutableListOf<Fragment>() private var lastfragment = 0 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) initFragment() initNavigationSelectedListener() } private fun initFragment() { val homeFragment = HomeFragment() val carFragment = CarFragment() val mineFragment = MineFragment() fragments.add(homeFragment) fragments.add(carFragment) fragments.add(mineFragment) supportFragmentManager.beginTransaction() .replace(R.id.fl_container, homeFragment) .show(homeFragment) .commit() } private fun switchFragment(index: Int) { if (lastfragment != index) { val transaction = supportFragmentManager.beginTransaction() //暗藏上个Fragment transaction.hide(fragments[lastfragment]) if (!fragments[index].isAdded) { transaction.add(R.id.fl_container, fragments[index]) } transaction.show(fragments[index]).commitAllowingStateLoss() lastfragment = index } } private fun initNavigationSelectedListener() { findViewById<BottomNavigationView>(R.id.bottom_navigation).setOnNavigationItemSelectedListener { item -> when (item.itemId) { R.id.nav_home -> { switchFragment(0) return@setOnNavigationItemSelectedListener true } R.id.nav_car -> { switchFragment(1) return@setOnNavigationItemSelectedListener true } R.id.nav_me -> { switchFragment(2) return@setOnNavigationItemSelectedListener true } } false } }}二、引入Flutter Module首先,创立一个Flutter Module工程。创立Flutter Module有两种形式,一种是应用Android Studio进行生成,另一种是间接应用命令行。应用命令行创立flutter module的如下: ...

January 8, 2022 · 3 min · jiezi

关于flutter:官方-征集-Flutter-桌面端应用程序的构建案例

敬爱的社区成员们,大家好! Google Flutter 团队心愿理解开发者们应用 Flutter 构建的桌面端应用程序,以进步 Flutter 桌面端的测试覆盖率,邀请大家通过表单的模式提交征集和反馈。本次征集首要思考专门为桌面端设计的应用程序 (不管是否有挪动端版本),除非在征集表格里示意违心被展现和宣传,Flutter 团队会为你的提交窃密。 征集表单信息蕴含: 应用程序名称产品性能形容 (可选)为哪些平台构建和公布 (Windows, macOS, Linux 等)利用类型 (外部、内部、demo 演示等)屏幕截图或者运行视频 (可选)利用下载 / 开源仓库地址 (可选)向 Flutter 团队分享你的桌面端构建体验和反馈以及电子邮箱地址 (可选)倡议应用英文或者翻译工具翻译为英文进行征集表格填写,请扫描下方图片辨认二维码,或者 点击这里 填写表单。 谢谢大家的工夫!

January 7, 2022 · 1 min · jiezi

关于flutter:Flutter-VS-React-Native跨端方案大-PK

2021 年 12 月 30 日,融云主办的业内首个程序员综艺“猿桌派”第二期开播。节目聚焦经久不衰的技术选型问题,是跨端还是原生?是 Flutter 还是 React Native? 以下为精彩回顾: 从老本和市场笼罩的角度来看,跨端计划的劣势是微小的,写一次即可全平台运行。 那么,跨端计划如何选?Flutter 还是 React Native? Flutter VS React Native:生态比照 通过 Flutter 和 React Native 在 GitHub 上的根底数据比照单方生态。 Flutter 的根底数据:Watch 3.6K,Fork 19.9K,Starred 134K。 Fork 代表潜在的开发者,有近两万人关注这门语言。Star 数自不必说,证实它的受欢迎水平。抉择第三方框架时,看 Star 数也会帮忙开发者升高筛选老本。 还有一个重要指标,Issues 数量。目前一共是 5K+,已敞开 5 万+。这些数据,都阐明团队在保护 Flutter 的社区上十分用心,及时解决用户在应用过程中遇到的问题。 React Native 的根底数据:Watch 3.7K,Fork 21.6K,Starred 100K。其实从工夫周期上看,React Native 的数据是有劣势的。在这个前提下,单方 Watch、Fork 分数相差无几,Star 数落后。联合工夫周期思考,Flutter 胜出。 Issues 数量 1.9K,比拟起来,Flutter 这个数值更大。首先,这可能是因为用的人多,而且波及端线多,问题必定更多;其次,Issues 不代表代码或框架有问题,也有可能是开发者在应用的时候单纯对一些设计不太了解。 所以,社区凋敝度:Flutter > React Native Flutter VS React Native:性能 PK ...

January 6, 2022 · 2 min · jiezi

关于flutter:vscodeflutter真机调试

flutter 学习笔记 1、不依赖Android Studio装置flutter(macos)https://zhuanlan.zhihu.com/p/... 2、在 .bash_profile里设置变量参考https://flutterchina.club/set... export PUB_HOSTED_URL=https://pub.flutter-io.cnexport FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn3、Flutter 命令每次都不失效,都须要重新配置环境变量的解决办法https://blog.csdn.net/weixin_... 4、在vscode中增加 ADB Interface for VSCode5、终端中找不到adb命令,在 .bash_profile里设置变量https://www.jianshu.com/p/196...https://www.jianshu.com/p/80d... export PATH=${PATH}:~/Library/Android/sdk/platform-tools之后F5报错 6、批改build.gradle,正文掉jcenter(),google()。应用阿里的镜像。起因是jcenter google库无法访问到导致的问题。https://blog.csdn.net/chichen... 7、之后 依据andriod-sdk的门路去更新 sdkmanager 和更新 licenses https://blog.csdn.net/weixin_... ./sdkmanager --update ./sdkmanager --licenses 8、解决io.flutter报错的问题https://www.jianshu.com/p/946...

January 5, 2022 · 1 min · jiezi

关于flutter:Flutter-让你的Dialog脱胎换骨吧AttachDialogLoadingToast

前言Q:你毕生中闻过最臭的货色,是什么? A:我那早已腐烂的梦。 兄弟萌!!!我又来了! 这次,我能自信的对大家说:我终于给大家带了一个,能真正帮忙大家解决诸多坑比场景的pub包! 将之前的flutter_smart_dialog,在放弃api稳固的根底上,进行了各种抓头重构,解决了一系列问题 当初,我终于能够说:它当初是一个简洁,弱小,侵入性极低的pub包! 对于侵入性问题 之前为了解决返回敞开弹窗,应用了一个很不优雅的解决办法,导致侵入性有点高这真是让我坐立不安,如芒刺背,如鲠在喉,这个问题终于搞定了!同时,我在pub包外部设计了一个弹窗栈,能主动移除栈顶弹窗,也能够定点移除栈内标记的弹窗。 存在的问题应用零碎弹窗存在一系列坑,来和各位探讨探讨 必须传BuildContext 在一些场景必须多做一些传参工作,蛋痛但不难的问题loading弹窗 应用零碎弹窗做loading弹窗,必定遇到过这个坑比问题 loading封装在网络库外面:申请网络时加载loading,手贱按了返回按钮,敞开了loading而后申请完结后发现:特么我的页面怎么被关了!!!零碎弹窗就是一个路由页面,关闭系统就是用pop办法,这很容易误关失常页面 当然必定有解决办法,路由监听的中央解决,此处就不细表了某页面弹出了多个零碎Dialog,很难定点敞开某个非栈顶弹窗 蛋蛋,这是路由入栈出栈机制导致的,了解的同时也一样要吐槽零碎Dialog,点击事件无奈穿透暗色背景 这个坑比问题,我是真没辙相干思考下面列举了一些比拟常见的问题,最重大的问题,应该就是loading的问题 loading是个超高频应用的弹窗,敞开loading弹窗的办法,同时也能敞开失常应用的页面,自身就是一个隐患穿透dialog遮罩是个十分重要的性能,基于该性能,可能在理论业务中,实现很多骚操作既然在零碎dialog难以解决各种痛点,加上零碎dialog也是基于overlay去实现的,这样的话,咱们也能够去高度定制overlay!这次,我要一次性帮各位解决:toast音讯,loading弹窗,以及更弱小的自定义dialog! 疾速上手初始化引入(最新版本请点击pub查看):pub,github,web effectdependencies: flutter_smart_dialog: ^3.2.0接入形式更加简洁void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage, // here navigatorObservers: [FlutterSmartDialog.observer], // here builder: FlutterSmartDialog.init(), ); }}极简应用toast应用SmartDialog.showToast('test toast'); loading应用⏳SmartDialog.showLoading();await Future.delayed(Duration(seconds: 2));SmartDialog.dismiss(); dialog应用var custom = Container( height: 80, width: 180, decoration: BoxDecoration( color: Colors.black, borderRadius: BorderRadius.circular(20), ), alignment: Alignment.center, child: Text('easy custom dialog', style: TextStyle(color: Colors.white)),);// hereSmartDialog.show(widget: custom, isLoadingTemp: false); ...

January 3, 2022 · 8 min · jiezi

关于flutter:Dart-215-现已发布

作者 / Michael Thomsen, Dart & Flutter Product Manager, Google 咱们曾经正式公布了 Dart SDK 的 2.15 版本,该版本新增了可疾速并发的工作器 isolate、新的构造函数拆分 (tear-off) 语言个性、通过改良的 dart:core 库枚举反对、package 发布者相干的新性能,等等。 工作器 isolate 的疾速并发现在,简直所有古代设施都应用多核 CPU,能够并行执行多个工作。对于大多数 Dart 程序来说,这些内核的应用状况对开发者而言是通明的: 默认状况下,Dart 运行时零碎在单个内核上运行所有的 Dart 代码,不过会应用其余内核来执行零碎级任务,比方异步输出/输入,包含写入文件或者调用网络等。 不过您本人的 Dart 代码可能也须要并发运行。例如,您可能须要展现一个间断的动画,同时执行一个长时间运行的工作,比方解析一个大型 JSON 文件。如果额定工作花了太长时间,就可能会导致界面卡顿或提早。如果将这些额定的工作挪动到另一个独自的内核,动画就能够在主执行线程上持续运行而不受烦扰。 Dart 的并发模型基于 isolate,isolate 是一种互相隔离的独立执行单元,这是为了避免出现与共享内存相干的大量并发编程谬误,如 数据争用等竞态条件。Dart 通过禁止在 isolate 之间共享任何可变对象来防止这些谬误,并应用 消息传递 在 isolate 之间替换状态。在 Dart 2.15 中,咱们对 isolate 进行了许多实质性的改良。 咱们首先从新设计和实现了 isolate 的工作形式,引入了一个新概念: isolate 组。Isolate 组中的 isolate 共享各种外部数据结构,这些数据结构则示意正在运行的程序。这使得组中的单个 isolate 变得更加轻便。现在,因为不须要初始化程序结构,在现有 isolate 组中启动额定的 isolate 比之前快 100 多倍,并且产生的 isolate 所耗费的内存缩小了 10 至 100 倍。 ...

December 30, 2021 · 4 min · jiezi

关于flutter:Flutter-最好的导航插件

前言一个好的导航对 APP 是很重要的,以下这些导航插件兴许对你一开始有帮忙。 不过好的体验还是要本人写。 原文https://tomicriedel.medium.co...注释 Curved Navigation Bar 有了这个包,你能够很容易地创立一个十分丑陋的导航栏,这是一个真正的吸引留神的形式。有一个十分好的动画和许多定制选项,这是一个十分好的扩大为您的下一个应用程序! Bottom Bar with Sheet是一个一般的底部栏,然而它提供了一个十分有用的性能。有时候你想在屏幕上有更多的空间,然而你是怎么做到的呢?嗯,非常简单: 有了这个导航条,你能够拉出一个“第二屏幕”/表,通过这样做,你失去更多的空间。上面是一个小例子: Convex Bottom Bar应用 Convex Bottom Bar,你能够创立令人印象粗浅的底部栏,肯定会吸引用户的眼球! Sliding Clipped Nav Bar提供了一个很好的形式,让你的应用程序对用户来说更乏味。因为其令人难以置信的简略的执行和漂亮的设计,它是最好的导航 Pub 包之一。 然而... ... 说够了,导航栏和这个包装看起来怎么样? 我想你很分明我为什么这么喜爱这个包裹。有这么多的定制可能性和实现非常简单。 Custom Navigation Bar这个导航栏为你提供了一个漂亮的动画底部 Pub ,它的灵感来自于一个对于运球的帖子。看看这些漂亮的动画吧: Persistent Bottom Navigation Bar应用这个包,你能够创立一个底部导航栏,它能够遍历多个子屏幕: © 猫哥 ducafecat.techgithubbilibili

December 29, 2021 · 1 min · jiezi

关于flutter:淘特-Flutter-流畅度优化实践

作者:谢伟(韦圣) 不同的业务背景引出不同的技术诉求,“用户体验特爽”是淘特的不懈谋求,本文将介绍笔者退出淘特以来在Flutter晦涩度方面的诸多优化实际,这些优化不波及Engine革新、不波及高大上的“轮子建设“,只需仔细粗疏深刻业务抽丝剥茧,保持理论体感导向,即能为用户体验带来显著晋升,值得Flutter开发者将其利用在产品的每一个像素。 背景淘特具备显明的三大特色: 业务特色:淘特领有业界最简单的淘系电商链路用户特色:淘特用户中有大量的中老年用户,大量的用户手机零碎版本较低,大量的用户应用中低端机技术特色:淘特大规模采纳Flutter跨平台渲染技术综上所述: 最简单业务链路+最低性能用户群体+最新的跨平台技术==>外围问题之一:页面晦涩度受到严厉挑战 Flutter外围链路20S疾速滚动帧率卡顿率(每秒卡顿率)直播Tab277.04%我的41.36667.63%详情26.715.58%注:相干数据以vivo Y67,淘特 3.32.999.10 (103) 测得 指标晦涩度是用户体验的要害一环,大家都不心愿手机用起来像看电影/刷PPT,尤其是当初高刷屏(90/120hz)的遍及,更是极大强化了用户对晦涩度的感知,但晦涩度也跟产品复杂度强相干,也是一次繁与简的取舍,淘特晦涩度一期优化指标: Flutter外围链路页面达到高晦涩度(均匀帧率:低端机45FPS、中端机50FPS、高端50FPS) 一期优化后的状态事项均匀帧率卡顿率晋升成果1.直播Tab举荐、分类栏目46.00.35%帧率进步19帧、卡顿率升高6.7%2.我的页面46.00%帧率进步4.6帧,卡顿率升高7.6%3.详情45.02%帧率进步18.3桢,卡顿率升高13.58%旧版3.32如视频左,新版3.37如视频右。因uiautomator工具会触发无障碍性能ISSUE,此版本比照为人工测试。 视频请见:淘特 Flutter 晦涩度优化实际 除了数据上的显著晋升,体感上,旧版快滑卡顿显著,画面渐变显著,新版则根本打消显著的卡顿,画面间断安稳。 问题回到技术自身,Flutter为什么会卡顿、帧率低?总的来说均为以下2个起因: UI线程慢了-->渲染指令出的慢GPU线程慢了-->光栅化慢、图层合成慢、像素上屏慢那么,怎么解上述的 2 个问题是咱们所关怀的重点。既然晓得某块有问题,咱们天然要有工具系统化的度量问题程度,以及系统化的实践撑持实际,且看以下2节,过程中交叉相干策略在淘特的实际, 实践与实际联合了解更透。 怎么解解法 - 案例升高setState的触发节点大家都晓得Flutter的刷新机制,在越高的Widget树层级触发setState标脏Element,“脏树越大”,在越低层级越部分的Widget触发状态更新,“脏树越小”,被标记为脏树后将触发Element.Rebuild,遍历组件树。原理请看下图“Flutter页面刷新机制源码解析”: “Element.updateChild源码剖析”请见下文优化二。 理论利用淘特为例。直播Tab的视频预览性能为例,最后直播Tab的视频播放index通过状态层层传递给子组件,一旦状态变更,顶层setState触发播放index更新, 造成整个页面刷新。但理论整个页面须要更新状态的只有“须要暂停的原VideoWidget”和“待播放的VideoWidget”, 咱们改为监听机制,页面中的所有VideoWidget注册监听,顶层用EventBus对立散发播放index至各VideoWidget,部分Widget Check后扭转本身状态。 再比方详情页,因为应用了“上一个页面借图”的性能,监听到滚动后暗藏借的图,但setState的调用节点放在了详情顶层Widget,造成了全局刷新。理论该监听刷新逻辑可下放至“借图组件”,升高“脏树”的大小。 缓存不变的Widget缓存不变的Widget有2大益处。1.被缓存的Widget将无需反复创立, 尽管Flutter官网认为Widget是一种十分轻量级的对象,在理论业务中,Build耗时过高仍是一种常见景象。2.返回雷同援用的Widget将使Flutter进行该子树后续遍历, 即Flutter认为该子树无变动无需更新。原理请看下图“Element.updateChild源码剖析” 利用场景以淘特理论页面为例。详情页局部组件应用了DXWidget,实践上组件内容一经创立后当次页面生命周期不会再有变动,此种状况即可缓存不变的Widget,防止反复动静渲染DX,进行子树遍历。 Feed流的Item组件,布局简单,创立老本较高,实践上创立一次后内容也不会再变动,但item可能被删除,此时应该用Objectkey惟一标识组件,避免状态错位。 缩小不必要的build(setState)直播Tab用到一个埋点曝光组件,通过DevTools查看,发现其在每一次进度回调中从新创立itemWidget,尽管这不会造成业务异样,但实践上itemWidget只需被创立一次,这块经排查是应用组件时误传了builder函数,而不是间接传itemWidget实例。 详情页的逻辑非常复杂,AppBar依据滚动间隔实时计算透明度,这会导致高频的setState,实际上透明度变动前后应该满足一个差值后才应刷新一次状态, 为了性能考量,透明度应该只有少数几种值变更。 多变图层与不变图层拆散在日常开发中,会常常遇到页面中大部分元素不变,某个元素实时变动。如Gif,动画。这时咱们就须要RepaintBoundary,不过独立图层合成也是有耗费,这块需实测把握。以淘特为例。 直播Feed中的Gif图是一直高频跳动,这会导致页面同一图层从新Paint。此时能够用RepaintBoundary包裹该多变的Gif组件,让其处在独自的图层,待最终再一块图层合成上屏。 同理, 秒杀倒计时也是电商常见场景, 该组件也实用于RepaintBoundary场景。 防止频繁的triggerGC因为AliFlutter的关系,咱们得以被动触发DartGC,但GC同样也是有耗费的,高频的GC更是如此。淘特之前因为iOS的内存压力,在列表滚动进行时ScrollEndNotification则会触发GC,ScrollEndNotification在每一次手Down->up事件后都会触发一次,如果用户屡次触摸,则会较为频繁的触发GC,实测影响Y67 4帧左右的性能,这块减少页面不可见时GC 和在Y67等android低端机关闭滑动GC,进步滑动性能。 大JSON解析子线程化Flutter的isolate默认是单线程模型,而所有的UI操作又都是在UI线程进行的,想利用多线程的并发劣势需新开isolate 或compute。无论如何await,scheduleTask 都只是延后工作的调用机会,依然会占用“UI线程”, 所以在大Json解析或大量的channel调用时,肯定要观测对UI线程的耗费状况。在淘特中,咱们在低端机开启json解析compute化,不阻塞UI线程。 尽量减少或降级Clip、Opacity等组件的应用Flutter中,Clip次要用于裁剪,裁矩形、圆角矩形、圆形。一旦调用,后续所有的绘图指令都会受其Clip影响。有些ClipRRect能够用ShapeDecoration代替,Opacitiy改用AnimatedOpacity, 针对图片的Clip裁切,能够走定制图片库Transform实现。 ...

December 27, 2021 · 1 min · jiezi

关于flutter:Flutter-Distributor-用于打包和发布-Flutter-应用的完整工具

介绍Flutter Distributor 是一个残缺的工具,用于打包和公布您的 Flutter 利用。只需通过一些简略的配置便能够让你的我的项目能够疾速的打包保留到指定目录及公布到指定的散发平台。 开发这个工具的起因是因为我的集体作品比译公布后,须要将它打包为 Linux,macOS 和 Windows 的平台特定的包格局并公布到 GitHub Releases,起初写了打包脚本,但前面须要反对的格局越来越多,每次版本公布都须要破费大量的工夫。因而从最后的脚本开始缓缓演变为 Flutter Distributor,从第一行代码到当初曾经过来了近两个半月,明天终于能够拿进去介绍给大家,心愿这个工具能够帮忙到大家。 个性将利用打包为特定平台的格局(同时反对桌面端),并将放入指定文件夹中。反对利用包文件按指定格局命名将利用包公布到指定的散发平台(目前只反对 apk, ipa 两种格局)已反对的包格局apkaabdebdmgexeipazip以上 apk, aab, ipa 为挪动软件包格局,其余为桌面软件包格局。已反对的散发平台firpgyer疾速开始装置dart pub global activate flutter_distributor用法将 distribute_options.yaml 增加到你的我的项目根目录,你也能够查看这个残缺示例 hello_world。 output: dist/配置一个公布器以 pgyer 为例,登录后,点击右侧的用户头像,从菜单中进入API 信息页面,复制 API Key 并将其增加到 env 节点。 env: PGYER_API_KEY: 'your api key'查看所有公布器文档以及如何配置它们。 配置公布项上面的例子展现了如何增加一个蕴含打包 apk、ipa 包并公布到 pgyer.com 的公布项,一个公布项能够蕴含多个作业。 build_args 是 flutter build 命令所反对的参数,请依据你的我的项目进行批改。releases: - name: dev jobs: - name: release-dev-android package: platform: android target: apk build_args: target: lib/main.dart flavor: dev target-platform: android-arm,android-arm64 # 当你不须要公布到散发平台,请删除 publish_to 字段 publish_to: pgyer - name: release-dev-ios package: platform: ios target: ipa build_args: target: lib/main.dart flavor: dev export-options-plist: ios/dev_ExportOptions.plist publish_to: pgyer残缺的示例配置env: PGYER_API_KEY: 'your api key'output: dist/releases: - name: dev jobs: - name: release-dev-android package: platform: android target: apk build_args: target: lib/main.dart flavor: dev target-platform: android-arm,android-arm64 publish_to: pgyer - name: release-dev-ios package: platform: ios target: ipa build_args: target: lib/main.dart flavor: dev export-options-plist: ios/dev_ExportOptions.plist publish_to: pgyer公布你的利用flutter_distributor release --name dev相干链接https://github.com/leanflutte...https://distributor.leanflutt...谢谢 ...

December 26, 2021 · 1 min · jiezi

关于flutter:不听话的-Container

前言在浏览本文之前咱们先来回顾下在 Flutter 开发过程中,是不是常常会遇到以下问题: Container 设置了宽高有效Column 溢出边界,Row 溢出边界什么时候该应用 ConstrainedBox 和 UnconstrainedBox每当遇到这种问题,我总是一直地尝试,费了九牛二虎之力,Widget 终于乖乖就范(达到现实成果)。痛定思过,我终于开始镇压(起来,不愿做奴隶的人们,国歌唱起来~),为什么 Container 设置宽高又有效了?Column 为什么又溢出边界了?怀揣着满腔热血,我终于鼓起勇气首先从 Container 源码动手,逐个揭开它的神秘面纱。 布局规定在讲本文之前,咱们首先应该理解 Flutter 布局中的以下规定: 首先,下层 Widget 向上层 Widget 传递约束条件其次,上层 Widget 向下层 Widget 传递大小信息最初,下层 Widget 决定上层 Widget 的地位如果咱们在开发时无奈纯熟使用这些规定,在布局时就不能齐全了解其原理,所以越早把握这些规定越好。 Widget 会通过它的父级取得本身束缚。束缚实际上就是 4 个浮点类型的汇合:最大/最小宽度,以及最大/最小高度。而后这个 Widget 将会一一遍历它的 children 列表,向子级传递束缚(子级之间的束缚可能会有不同),而后询问它的每一个子级须要用于布局的大小。而后这个 Widget 将会对它子级 children 一一进行布局。最初,Widget 将会把它的大小信息向上传递至父 Widget(包含其原始约束条件)。严格束缚(Tight)vs. 宽松束缚(Loose)严格束缚就是取得确切大小的抉择,换句话来说,它的最大/最小宽度是统一的,高度也是一样。 // flutter/lib/src/rendering/box.dartBoxConstraints.tight(Size size) : minWidth = size.width, maxWidth = size.width, minHeight = size.height, maxHeight = size.height;宽松束缚就是设置了最大宽度/高度,然而容许其子 Widget 取得比它更小的任意大小,换句话说就是宽松束缚的最小宽度/高度为 0。 // flutter/lib/src/rendering/box.dartBoxConstraints.loose(Size size) : minWidth = 0.0, maxWidth = size.width, minHeight = 0.0, maxHeight = size.height;Container 局部源码首先奉上 Container 局部源码,上面咱们会联合具体场景对源码进行逐个剖析。 ...

December 24, 2021 · 6 min · jiezi

关于flutter:Flutter-高性能多功能的全场景滚动容器原理与实践

作者:新宿、光酒 目前闲鱼的次要业务场景都曾经应用 Flutter 来实现,其中流式布局是最常见的页面布局场景(如搜寻、商品详情等)。随着业务的疾速迭代和业务复杂度的一直晋升,对流式场景的能力和性能要求也越来越高; 在能力方面,最常见的如卡片曝光、滚动锚点、瀑布流布局等能力,随着业务和需要的一直变动,Flutter原生和一些开源解决方案,慢慢无奈满足咱们需要;性能方面,流式场景下的列表滚动晦涩度问题随着业务复杂度的减少而逐步好转,亟需解决以晋升用户的应用体验。针对以上在业务中面临的问题,咱们设计了一套流式场景下通用的页面布局解决方案,咱们将其命名为 PowerScrollView。 整体架构设计在架构设计之前,咱们充沛调研了原生 Native 的滚动容器:UICollectionView(iOS) 和 RecyclerView(Android)。其中UICollectionView 的 Section(段落)理念令咱们印象粗浅,RecyclerView 的架构设计也启发了咱们。因为 Flutter 的独特性,咱们不能将其照搬过去,所以咱们的指标是联合 Native 成熟的滚动容器,加以 Flutter 的特点,设计出更加优良的滚动容器。 Flutter 原生有罕用的 ListView、GridView,他们布局较为繁多,性能较为简单。官网也提供了CustomScrollView的进阶Widget,CustomScrollView由多个 Sliver 进行拼接,以适应更简单的应用场景,咱们将基于 CustomScrollView 进行设计。 从应用角度登程,整个列表由若干个 Section 组成,又将 Section 分为 header、content、footer 三局部,header 为段落的头部,个别可作为 Section 的头部装璜,反对是否吸顶;footer 为段落的尾部,作为 Section 的尾部装璜。列表领有下拉刷新与加载更多能力;content 为 Section 的注释,反对常见的布局形式:列表、网格、瀑布流以及自定义。Section 的 content 由任意个 cell 组成,cell 即为列表最小粒度的 item。 从 Flutter 原生容器登程,CustomScrollView 反对任意多个 Sliver 的组合,Sliver 提供了 SliverList、SliverGrid、SliverBox 等,已根本合乎了咱们要求。咱们将 Section 的 header 和 footer 各对应一个 SliverBox,content 对应 SliverList 或SliverGrid,再独自为瀑布流布局开发一个 SliverWaterfall;再在整个列表的头部和尾部插入用于刷新加载更多的 Sliver。 ...

December 23, 2021 · 3 min · jiezi

关于flutter:15-个-JavaScript-代码示例及其-Dart-对应代码

做为 开发过React/React Native 的工程师,在刚开始接触Flutter 开发的时候,肯定会遇到这种状况,对于某个性能你能很纯熟应用特定Javascript语法去实现,然而对于Flutter 开发,对应的Dart的语法又是什么?往往要再打开Dart文档去寻找对应的语法。在此分享15 个 JavaScript 代码示例及其 Dart 对应代码。 1. JSON.stringify 和 JsonEncoder().convert在 JavaScript 中,如果要将对象转换为 JSON 字符串,能够应用: JSON.stringify(yourObject)在 Dart 中,只需导入'dart:convert'即可应用: import 'dart:convert'; JsonEncoder().convert(yourObject)2. JSON.parse和JsonDecoder().convert在 JavaScript 中将 JSON 转换为对象,会应用以下代码: JSON.parse(yourJson)在 Dart 中,只需导入'dart:convert'即可应用: import 'dart:convert'; JsonDecoder().convert(yourJson)3. array.push和list.add在 JavaScript 中,要增加'hello'到数组中,能够应用 array.push('hello')在 Dart 中,这样应用, list.add('hello')4. array.splice和list.sublist在 JavaScript 中,数组删除第一个元素(索引值为0) array.splice(0, 1)在Dart中, 返回索引范畴(1 和 3)内的新列表 list.sublist(1, 3)5. array.splice和list.removeAtarray.splice与#4点一样 在Dart中, 删除索引值为itemIndex的值 list.removeAt(itemIndex)6. array.length > 0和list.isNotEmpty查看数组是否为空 ...

December 21, 2021 · 1 min · jiezi

关于flutter:Flutter-28-更新详解

北半球的冬意已至,黄叶与气温均随风而落。年初的最初一个 Flutter 稳固版本 已悄悄来到你的背后。让咱们向 Flutter 2.8 打声招呼~ 本次更新蕴含了 207 位贡献者和 178 位审核者 的辛勤劳作,所有人独特产出了 2424 个 PR,敞开了 2976 个 issue。在此特别感谢本次公布中最突出的社区贡献者: 来自 VGV 的 Flutter 开发工程师 Bartosz Selwesiuk,他为 Web 平台的 camera 插件并提交了 23 个 PR。 以上的所有产出让 Flutter 引擎和开发者工具 (DevTools) 都有了十分显著的性能晋升,同时带来的还有 Google 挪动端广告 SDK Flutter 版本的稳定版公布、一系列针对 Firebase 的新性能和优化、Flutter WebView 3.0、新的 Flutter Favorite package、向桌面端稳定版迈出的一大步,以及反对更多 package 的新版 DartPad。让咱们一起来看看吧! 性能晋升Flutter 的首要指标是判若两人地保障其品质。咱们破费了大量工夫以确保 Flutter 在多种多样的设施上都能流畅且稳固地运行。 利用启动性能本次更新优化了利用启动的提早。咱们在领有一百万行以上的代码量的 GPay 利用上进行了测试,以确保改变在理论生产的利用上无效。这些改变将 GPay 在低端 Android 设施上启动的工夫缩小了约 50%、高端设施上缩小了约 10%。 咱们对 Flutter 调用 Dart VM 的 GC 策略也做了一些改良,以此防止在程序启动期间呈现不合时宜的 GC。例如,在 Android 设施上渲染出第一帧前,Flutter 仅在 TRIM_LEVEL_RUNNING_CRITYCAL 及高于其等级的信号呈现时,告诉 Dart VM 有内存压力。在本地测试中,低端 Android 设施的初始帧呈现间隔时间最多缩小了约 300ms。 ...

December 15, 2021 · 6 min · jiezi

关于flutter:技术实践第二期|Flutter异常捕获

简介:利用性能稳固是良好用户体验中十分要害的一环,为了更好保障利用性能稳固,异样捕捉在保障线上产品稳固中扮演着至关重要的角色。咱们团队在推出了U-APM挪动利用性能监控的产品后,帮忙开发者定位并解决掉很多线上的疑难杂症。随着应用人数的增多,关注度的进步,在访问客户和开发者的留言中,很多开发者都提出心愿该产品能够反对flutter框架的异样捕捉。自身我并没有做过flutter开发,所以次要是通过在现有产品能力根底上做插件实现异样的上报,这篇文章就记录我学习flutter错误处理的过程和遇到的问题。 作者:友盟+技术专家 彦克 一、背景利用性能稳固是良好用户体验中十分要害的一环,为了更好保障利用性能稳固,异样捕捉在保障线上产品稳固中扮演着至关重要的角色。咱们团队在推出了U-APM挪动利用性能监控的产品后,帮忙开发者定位并解决掉很多线上的疑难杂症。随着应用人数的增多,关注度的进步,在访问客户和开发者的留言中,很多开发者都提出心愿该产品能够反对flutter框架的异样捕捉。自身我并没有做过flutter开发,所以次要是通过在现有产品能力根底上做插件实现异样的上报,这篇文章就记录我学习flutter错误处理的过程和遇到的问题。 二、Flutter异样Flutter 异样指的是,Flutter 程序中 Dart 代码运行时意外产生的谬误事件。 三、Flutter异样特点Dart是单过程机制,所以在这个过程中呈现问题时仅仅会影响以后过程,Dart 采纳事件循环的机制来运行工作,当某个工作产生异样并没有被捕捉时,程序并不会退出,而间接导致的后果是当前任务的后续代码就不会被执行了,也就是说一个工作中的异样是不会影响其它工作执行的,各个工作的运行状态是相互独立的。 如:咱们能够通过与 Java 相似的 try-catch 机制来捕捉它。但与 Java 不同的是,Dart 程序不强制要求咱们必须解决异样。 四、Flutter异样分类在Flutter开发中,依据异样起源的不同,能够将异样分为Framework异样和App异样。Flutter对这两种异样提供了不同的捕捉形式,Framework异样是由Flutter框架引发的异样,通常是因为谬误的利用代码造成Flutter框架底层的异样判断引起的。而对于App异样,就是利用代码的异样,通常由未解决应用层其余模块所抛出的异样引起。依据异样代码的执行时序,App 异样能够分为两类,即同步异样和异步异样。 五、捕捉形式1.App 异样的捕捉形式捕捉同步异样应用try-catch 机制: // 应用 try-catch 捕捉同步异样try { throw StateError('This is a Dart exception.');}catch(e) { print(e);}捕捉异步异样应用Future 提供的 catchError 语句: // 应用 catchError 捕捉异步异样Future.delayed(Duration(seconds: 1)) .then((e) => throw StateError('This is a Dart exception in Future.')) .catchError((e)=>print(e));看到这里预计很多人心里会问,就不能有一种形式既能够监控同步又能够监控异步异样吗? 答案是有的。 Flutter 提供了 Zone.runZoned 办法来治理代码中的所有异样。咱们能够给代码执行对象指定一个Zone,在 Dart 中,Zone 示意一个代码执行的环境范畴,其概念相似沙盒,不同沙盒之间是相互隔离的。如果咱们想要察看沙盒中代码执行呈现的异样,沙盒提供了 onError 回调函数,拦挡那些在代码执行对象中的未捕捉异样。废话不多说, Show me the code!runZoned(() { // 同步异样 throw StateError('This is a Dart exception.');}, onError: (dynamic e, StackTrace stack) { print('Sync error caught by zone');});runZoned(() { // 异步异样 Future.delayed(Duration(seconds: 1)) .then((e) => throw StateError('This is a Dart exception in Future.'));}, onError: (dynamic e, StackTrace stack) { print('Async error aught by zone');});为了可能集中捕捉 Flutter 利用中的未解决异样,最终我把main函数中的 runApp 语句也搁置在 Zone 中。这样在检测到代码中运行异样时,就能依据获取到的异样上下文信息,进行对立解决了: ...

December 13, 2021 · 2 min · jiezi

关于flutter:Flutter-28-正式发布

文/ Tim Sneath,Flutter & Dart 产品经理 Flutter 曾经更新到 2.8 正式版,公布了多项新个性和改良以一直改善挪动和 Web 端的开发体验,同时也正在将桌面端的反对推向稳定版。 Flutter 为利用开发带来了变革:只有一套代码库,即可构建、测试和公布实用于挪动、Web、桌面和嵌入式平台的精美利用——开发者只需专一于他们心愿构建的产品和服务,而无需首要思考公布到哪些平台;作为一个高性能、高生产力的开发框架,Flutter 也能够帮忙开发者们缩短产品开发周期;一套代码库,针对多个平台。 新个性和改良: 更疾速、更高效这次正式版次要关注的是 挪动平台性能。现实状况下,杰出的性能应该是「标配」,但在实践中,所有大型或简单业务的利用都须要针对硬件和零碎 API 库进行优化。这包含但不仅限于比方利用启动,可能会受限于网络带宽和其余代码初始化的耗费,内存耗费,可能会受制于局部内存无限的设施,以及图形渲染性能等。咱们也始终在借助外部的大型利用比方 Google Pay 对 Flutter 的应用来进步 Flutter 的性能体现,并提供更好的工具来调试和剖析利用性能。为你的工程降级到 Flutter 2.8 正式版,你的利用应该会有更少的内存占用以及更快的启动速度。 最新的更新也蕴含了更不便的 利用接入后端服务 的个性,比方应用 Firebase 和 Google Cloud。咱们也为利用能够退出 Google Ads 提供了稳定版的反对,并对相机插件和 Web 插件内嵌提供了大量更新。与此同时公布的还有 Dart 2.15 正式版,减少了对并发性能的重大改良,也增加了新的语言个性,比方构造函数拆分和枚举类型的加强,也进行了性能优化,使得运行时内存升高了 10%。 另一个重要话题和资源投入是「晋升开发者效率」,得力于 Flutter 的有状态热重载 (stateful hot reload) 等个性,咱们始终专一于为开发者创立一个紧凑的外部循环迭代流程,咱们正在开始摸索封装出一些更高级的性能让开发者们更疾速和高效的应用,你也能在将来的版本里看到咱们针对这个指标的改良。比方在此次正式版公布里,咱们增加了一个应用 Firebase 解决身份验证的 widget,应用的时候毋庸放心任何非凡的用例,比方两步验证、明码重置的操作,也不必操心应用 Google、Apple、Twitter 和 Facebook 账号登陆时的简单状况。将这些个性和服务间接构建在 Flutter 的外围根底中,将有可能为利用开发带来变革,将高效开发和低代码计划相结合,利用在 Flutter 这个灵便和弱小的 UI 框架上。 应用基于 Flutter 的游戏开发框架 Flame对于大部分开发者来说,Flutter 是一个利用框架。不过应用 Flutter 进行休闲小游戏开发的生态也在一直倒退,这些小游戏借助 Flutter 实现硬件图形减速。 ...

December 9, 2021 · 2 min · jiezi

关于flutter:Flutter-2-渲染原理和如何实现视频渲染

7 月 17 日下午,在前端专场巡回沙龙北京站中,声网Agora跨平台开发工程师卢旭辉带来了《Flutter2 渲染原理和如何实现视频渲染》 的主题分享,本文是对演讲内容的整顿。 本次分享次要包含 3 个局部: Flutter2 概览。Flutter2 视频渲染插件的实际。Flutter2 渲染原理(源码)。前言其实 Flutter1 在国内的占有率并不算高,很多开发者可能晓得 Flutter 的下层语言是基于 Google 的 Dart (一个已经希图取代 JavaScript 的语言,但最初以失败告终),而Dart语言也是很多开发者不太能承受Flutter的点。国内很多公司可能还是选用 ReactNative 或者保持原生开发,不过随同着 Flutter2 的问世(全平台反对),以及阿里的北海框架(基于 Flutter Engine 的渲染能力实现的下层应用 JavaScript 的跨平台框架),我置信 Flutter2 将来可期。思考到很多读者可能是前端开发者,所以在第三局部我会以 Web 的视角切入,大家会看到很多相熟又生疏的内容,是不是 Flutter 开发者或者是否理解 Flutter 都不重要,重要的是 Flutter 的设计思维,心愿对大家有所帮忙。 Flutter2 概览Flutter2 是 Google 在 2021 年 3 月份公布的 Flutter 最新版本,它基于 Dart1.12 反对了 Null-Safety (空安全检查),大家能够类比TypeScript的"?",编译器会要求你对可能为空的数据进行校验,这样能够在开发过程中防止一些空指针的问题。而更为重要的就是对 Web 端提供了稳定版的反对,对桌面端的反对也曾经合入。 上面咱们一起看下 Flutter2 的整体架构: Flutter2 的 Web 局部包含 Framework 层和 Browser 层,其中 Framework 层涵盖渲染、绘制、手势解决等,Browser 层涵盖 CSS、HTML、Canvas、WebGL 等(毕竟还是在浏览器上运行),而最初的 WebAssembly 是为了应用 C 和 C++ 从而调度 Skia 渲染引擎,这个咱们在第三局部也会具体介绍。 ...

December 7, 2021 · 5 min · jiezi

关于flutter:Flutter开源项目-appFlowy-真的是-Notion-的替代品-一周暴涨-star-9k-多

githttps://www.appflowy.io/ https://github.com/AppFlowy-I... 也就 1 周 star 9.8k,我认为他是刷的。指标&特色指标代替 Notion数据 100% 本人治理开源形式提供,你能够本人改多平台反对原生体验,预计是用了 flutter 关系编译运行git clonegit clone https://github.com/AppFlowy-IO/appflowy.git装置 rustcd appflowy/frontendmake install_rustsource $HOME/.cargo/envmake install_cargo_makecargo make install_targets切换 flutter devflutter channel devorfvm use devfvm global devflutter 启用 desktop# for windowsflutter config --enable-windows-desktop# for macosflutter config --enable-macos-desktop# for linuxflutter config --enable-linux-desktop用 vscode 或者其它 idea 关上open appflowy/frontend 代码架构技术选型 flutter: 多端适配rust: ffi 平台接口、服务端flutter 端 frontend/app_flowy 前端业务 rust 层 frontend/rust-lib 共享库 shared-lib shared-lib 后端 rust api backend ...

December 3, 2021 · 3 min · jiezi

关于flutter:新版-Flutter-中文开发者网站发布

Develop as One,2021 年 Google 开发者大会 (Google Developer Summit) 于上个月顺利举办,蕴含泛滥最新 Google 技术产品更新的线上演讲,干货满满。 在 11 月 16 日上午进行的主题演讲中提到,目前国内的开发者数量有 500 万以上,约占寰球开发者数量的五分之一,中国的游戏开发商在头部的海内游戏市场份额超过 23%,排名第一,利用和游戏开发仍是一个值得继续投入并且领有更广大前景空间的市场。 Flutter 在这其中也表演了相当重要的角色。首先是头部厂商驳回,咱们看到字节跳动有 70 多款利用正在应用 Flutter,腾讯在其 企业微信 和 PUBG 手游上也应用 Flutter 构建新的性能,以及往年早些时候提到的贝壳找房也在 用 Flutter 构建一些外围性能。其次,不断完善的 Flutter 产品曾经成为了开发者们不可或缺的「秘密武器」——3 年前正式公布的时候,咱们将其定义为「便携式的 UI 工具包」,到当初进化成「一个为环境计算打造的 UI 平台」,开发者们只须要写一套代码,便可为所有屏幕构建精美利用,包含挪动端、Web 端、桌面端和嵌入式设施平台。最初,寰球的 Flutter 开发者数量达 300 万以上,当你开始写下 Flutter 的第一行 Hello World! 的时候,你也就退出成为寰球小家庭中的一员。 在此次开发者大会上,Flutter 团队也颁布和回顾了一些近期的更新,包含: Flutter 的桌面端反对在近期所做出了的大量改良,下一步打算是 Windows 端的无障碍性能优化和改良;Flutter Web 的 CanvasKit 渲染器稳定版已公布,能够通过 flutter run -d chrome --web-renderer canvaskit 应用;Flutter 版的 谷歌挪动广告插件正式公布 1.0 版本 (反对空平安),反对退出 AdMob 和 Ad Manager 广告,并反对各种广告模式,包含横幅广告、插页式广告、激励视频广告和原生广告。正式版也退出了广告中介的 beta 反对,通过 pub 命令 flutter pub add google_mobile_ads 即可开始应用;介绍和回顾了其余无关应用 Flutter 进行盈利的插件,包含应用利用内购买的 in_app_purchase 插件、集成应用多种付款形式的 pay 插件,都能帮忙你更好的通过 Flutter 盈利。DartPad 和 Flutter 网站更新DartPad 是一个开源的线上编译和运行 Flutter / Dart 代码的平台,它能够帮忙你 不便的学习和试验 Dart 编程语言个性,也能够将程序的最小可复现代码 分享给其余开发者一起交换探讨,咱们也制作了大量可交互的 Codelab,其中就内嵌了 DartPad,让你学习起来更不便、更直观、更乏味。 ...

December 2, 2021 · 2 min · jiezi

关于flutter:为了更好的-Flutter-2021-第四季度开发者调研

第三季度末,咱们公布了 Flutter 的又一个稳固版本 2.5 正式版,为开发者带来了很多重要的 性能晋升和开发者工具的改良;同时公布的还有 Dart 2.14 正式版,反对了 Apple 芯片,退出了 共享的代码规定,并对局部 语言个性 进行了更新;此外,咱们还颁布了 Flutter Web 的重要更新和路线图,包含 缩小滚动时的卡顿、对 相机插件的更新、改善 CanvasKit 的大小 等。在近期胜利举办的 2021 Google 开发者大会上,咱们也 颁布 了一些对于桌面端、Web 端的改良,重点提及了 应用 Flutter 进行盈利的相干内容,同时也公布了 新版的 Flutter 中文网站 (flutter.cn),也为 DartPad 退出了 援用第三方 package 的性能 等。 第四季度的 Flutter 开发者调查表曾经公布,咱们心愿邀请每一位 Flutter 开发者参加咱们。站在社区角度,咱们的指标比拟间接——通过每一期的调查表我的项目,收集更多的反馈和倡议,以推动 Google 官网以及寰球的 Flutter 贡献者优先思考和实现国内开发者的性能需要和改良倡议 。 因而,转发或者参加调研都能够让 Flutter 变得更好,谢谢你为 Flutter 做出的奉献! 请扫描下方图片中的二维码,或者 点击这里 参加此次调研,本调研问卷齐全匿名,本次调研将于 2021 年 12 月 3 日截止,谢谢你的工夫和参加。

November 30, 2021 · 1 min · jiezi

关于flutter:Flutter-和-pubspec-文件

概述每个 Flutter 我的项目都蕴含一个pubspec.yaml文件,通常称为pubspec。创立新的 Flutter 我的项目时会在我的项目根目录下生成这个文件,指定我的项目所需的依赖项,例如特定的包(及其版本)、字体或图像文件。它还指定了其余要求,例如对开发人员包的依赖(如测试或模仿包),或对 Flutter SDK 版本的特定限度;pubspec 用YAML编写的 ,还须要留神空格(制表符与空格)的书写。 pubspec.yaml 文件示例name: flutter_study_appdescription: A new Flutter project.# 以下行是避免包被意外公布到# pub.dev 应用`pub publish`。这是私人包的首选。publish_to: 'none' # 如果您心愿公布到 pub.dev,请删除此行# 应用程序的版本和外部版本号version: 1.0.0+1environment: sdk: ">=2.7.0 <3.0.0"dependencies: flutter: sdk: flutter # 增加插件库依赖,如下是创立flutter我的项目自带增加好的图标库 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.0dev_dependencies: flutter_test: sdk: flutter# For information on the generic Dart part of this file, see the# following page: https://dart.dev/tools/pub/pubspec# The following section is specific to Flutter.flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # 给应用程序增加assets文件, 比方本地须要用到ic_launcher.png,则如下增加引入: assets: - assets/images/ic_launcher.png # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware. # For details regarding adding assets from package dependencies, see # https://flutter.dev/assets-and-images/#from-packages # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/custom-fonts/#from-packages包名称和形容name为以后我的项目包的名称(不是程序名称),每个包都须要一个名称,对于命名规定,名称应全副小写,用下划线分隔单词;另外也要确保名称是无效的 Dart 标识符,不以数字结尾。 ...

November 28, 2021 · 2 min · jiezi

关于flutter:Flutter与一些常用的Dart语法

前言 上一次写了flutter相干的文章还是在7月份,现在都flutter2.5正式版了,官网都面目一新了。 于是乎,不要等了是时候学习了,开始记录下flutter开发过程中dart的一些罕用语法,能够帮忙咱们事倍功半。 对于Dart Dart 是一门为全平台构建疾速利用的客户端优化的编程语言,它的长处如下: 为 UI 构建:优化应用针对用户界面的发明进行优化的语言进行开发研发生产力进步:可重复地批改,而后在正在运行的利用中应用热重载立即看到您的批改在全平台极速运行:可编译为挪动端、桌面端及后端的 ARM & x64 的二进制文件,或是为 Web 平台编译 Javascript 接下来次要记录Flutter开发中罕用的dart语法,而后如何更方便快捷地实现一些flutter小小的性能。对于更多Dart相干的知识点,这里不会一一赘述,不过咱们能够到官网系统性地学习Dart语言,这也是Flutter开发的必备语言,官网地址如下:Dart:https://dart.cn/ List数组的罕用办法数组 (Array) 是简直所有编程语言中最常见的汇合类型,在 Dart 中数组由 List 对象示意。接下来使用应用dart工具来运行这些罕用的办法,工具:https://dartpad.cn 定义固定长度数组void main() {  var list = List(2);  print('$list'); // [null, null]}定义混合类型数组void main() {  var list = List<dynamic>();  list.add('我是文本');  list.add(0.66);  print(list); // [我是文本, 0.66]}获取数组第一个元素void main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  print(list.first); // 1}获取数组最初一个元素void main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  print(list.last); // 6}获取倒序迭代器 - reversedvoid main() {   var list = [1, 2, 2, 3, 4, 5, 6, 6];   print(list.reversed); // (6, 6, 5, 4, 3, 2, 2, 1)}批量增加 - addAll或者 扩大操作符(...)和 空感知扩大操作符(...?)void main() {   var list = [1, 2, 2, 3, 4, 5, 6, 6];  var list2 = [0, 20, 40];  list.addAll(list2);  print(list); //[1, 2, 2, 3, 4, 5, 6, 6, 0, 20, 40]}或应用扩大操作符,后果是一样的 void main() {  var list2 = [0, 20, 40];  var list = [1, 2, 2, 3, 4, 5, 6, 6, ...?list2];  print(list); //[1, 2, 2, 3, 4, 5, 6, 6, 0, 20, 40]}判断数组内是否有满足条件的元素- anyvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];// 数组中是否有大于3的元素  print(list.any((v) => v > 3)); // true// 数组中是否有大于7的元素  print(list.any((v) => v > 7)); // false}判断数组所有元素是否都满足设定条件 - everyvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];// 数组中所有元素是否都大于0  print(list.every((v) => v > 0)); // true// 数组中所有元素是否都大于5  print(list.every((v) => v > 5)); // false}获取满足条件的元素 - wherevoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  // 获取所有大于3的元素  print(list.where((v) => v > 3).toList()); //[4, 5, 6, 6]}获取满足条件的第一个元素 - firstWherevoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  // 获取最初一个大于3的元素  print(list.firstWhere((v) => v > 3)); // 4  // 如果未查找到所制订条件的元素,进入orElse参数  list.firstWhere((v) => v > 6, orElse: () {    print(888);  });}获取满足条件的最初一个元素 - lastWhere (与firstWhere同理,第一个与最初一个的区别) 从指定地位开始,获取满足条件的第一个元素的索引 - indexWherevoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  // 查问第一个大于3的元素索引值  print(list.indexWhere((v) => v > 3)); // 4// 从索引3开始,查问第一个大于4的元素索引值  print(list.indexWhere((v) => v > 4, 3)); // 5// 从索引3开始,查问第一个大于6的元素索引值// 若不存在,返回-1  print(list.indexWhere((v) => v > 6, 3)); // -1}获取满足条件的最初一个元素的索引(顺叙查问) - lastIndexWhere(与indexWhere同理,第一个与最初一个的区别) 从指定地位开始,获取指定值的索引 - indexOfvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  // 从索引6开始,获取5第一次呈现时的索引值,如果不存在,返回 -1  print(list.indexOf(5, 6)); // -1  print(list.indexOf(5)); // 5}从指定地位开始,顺叙获取指定值的索引 - lastIndexOf(与indexOf同理,第一次与最初一次的区别) 将数组用指定字符拼接成字符串 - joinvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  // 将数组转换为用英文逗号拼接的字符串  print(list.join(',')); // 1,2,2,3,4,5,6,6}数组去重 - toSetvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  print(list.toSet()); // {1, 2, 3, 4, 5, 6}}数组遍历 - for\for in\forEachvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  //for  for (var i = 0; i < list.length; i++) {    print("for:$i");  }  //for in  for (var item in list) {    print("for in:$item");  }  //forEach  list.forEach((element) {    print("forEach:$element");  });}按指定条件返回 - mapvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];  // 将list所有元素加1并返回数组  var v = list.map((e) {    return e + 1;  }).toList();  print(v); //[2, 3, 3, 4, 5, 6, 7, 7]}累加器 - reducevoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];// 将每次返回值作为value循环执行。最终返回最初一次执行值  var count = list.reduce((value, element) {    print('value: $value - element: $element');    /**    每次的执行后果    value: 1 - element: 2    value: 3 - element: 2    value: 5 - element: 3    value: 8 - element: 4    value: 12 - element: 5    value: 17 - element: 6    value: 23 - element: 6  */    return value + element;  });  print('count: $count'); // count: 29}排序 - sortvoid main() {  var list = [1, 2, 2, 3, 4, 5, 6, 6];// a - b 为升序, b - a为降序  list.sort((a, b) {    return b - a;  });  print(list); //[6, 6, 5, 4, 3, 2, 2, 1]}条件表达式与if语句~在布局中应用在flutter开发写页面时,常常都会解决一些判断逻辑,比方什么时候显示xxx按钮,什么时候暗藏xxx布局,这里罕用的就是条件表达式与if判断语句了。 举个例子,如上图 当初页面上有文本显示和一个button1,我要暗藏页面的button1, 应用条件表达式: ...

November 28, 2021 · 1 min · jiezi

关于flutter:淘特-Flutter-流式场景的深度优化

作者:江泽军(眞意) 淘特在很多业务场景都应用了 Flutter,加上业务场景自身具备肯定的复杂性,使得 Flutter 在低端机流式场景的滑动浏览过程中卡顿、跳帧比照应用原生(Android/iOS)开发显著。通过剖析业务层在 Flutter 渲染流程中的每个阶段存在的性能问题进行了一系列的深度优化后,均匀帧率曾经达到50帧之上超过了原生的体现, 但卡顿率仍然达不到最佳的体验成果,遇到了难以冲破的瓶颈和技术挑战,须要进行技术尝试和冲破。 本文会从底层原理、优化思路、理论场景的优化策略、核心技术实现、优化成绩等方面进行讲述,冀望能够为大家带来肯定的启发和帮忙,也欢送多多交换与斧正,共建美妙的 Flutter 技术社区。 渲染机制原生 vs FlutterFlutter 自身是基于原生零碎之上的,所以渲染机制和 Native 是十分靠近的,援用 Google Flutter 团队 Xiao Yu分享[1],如下图所示: 渲染流程如图左中,Flutter 从接管到 VSync 信号之后整体经验 8 个阶段,其中 Compositing 阶段后会将数据提交给GPU。 Semantics 阶段会将 RenderObject marked 须要做语义化更新的信息传递给零碎,实现辅助性能,通过语义化接口能够帮忙有视力阻碍的用户来了解UI内容,和整体绘制流程关联不大。 Finalize Tree 阶段会将所有增加到 _inactiveElements 的不沉闷 Element 全副 unmount 掉,和整体绘制流程关联不大。 所以,Flutter 整体渲染流程次要关注 上图图右 中的阶段: GPU Vsync Flutter Engine 在收到垂直同步信号后,会告诉 Flutter Framework 进行 beginFrame,进入 Animation 阶段。 Animation 次要执行了 transientCallbacks 回调。Flutter Engine 会告诉 Flutter Framework 进行 drawFrame,进入 Build 阶段。 ...

November 26, 2021 · 7 min · jiezi

关于flutter:千相千面图形语法

在 Flutter 可视化库 Graphic 的新版本中,优化了申明式定义的语法,使其更好的体现图形语法的实质。 本文通过 Graphic 的图形语法定义变换,一步步将柱状图演变为饼图,展现图形语法的灵便丰盛。同时也让初学者理解图形语法基本概念。 如果你从未接触过图形语法,不影响本文的浏览。本文能够看作 Graphic 的入门教程。 柱状图和饼图都是数据可视化中常见的类型,它们乍一看迥异,但在图形语法中,却有着雷同的实质,这是为什么?让咱们从柱状图一步步变换成饼图,来理解其中的原因。 首先从最常见的柱状图开始说起。数据采纳和 ECharts 的入门示例 一样: const data = [ {'category': 'Shirts', 'sales': 5}, {'category': 'Cardigans', 'sales': 20}, {'category': 'Chiffons', 'sales': 36}, {'category': 'Pants', 'sales': 10}, {'category': 'Heels', 'sales': 10}, {'category': 'Socks', 'sales': 20},];申明式定义Graphic 采纳申明式定义,所有的可视化语法都在图表组件 Chart 的构造函数中体现: Chart( data: data, variables: { 'category': Variable( accessor: (Map map) => map['category'] as String, ), 'sales': Variable( accessor: (Map map) => map['sales'] as num, ), }, elements: [IntervalElement()], axes: [ Defaults.horizontalAxis, Defaults.verticalAxis, ],)数据与变量图表的数据通过 data 字段引入,能够是任意类型的数组。在图表的外部,这些数据项将被转换成规范的 Tuple 类型。数据项如何转换为 Tuple 中的字段值则由变量(Variable)定义。 ...

November 23, 2021 · 2 min · jiezi

关于flutter:这可能是Flutter-中最强悍的内存泄漏检测方案

作者:吴志伟 近两年来,无论是创新型利用还是老牌旗舰型利用,都在或多或少地应用 Flutter 技术。然而,目前 Flutter 业务团队反馈最广泛的问题是,Flutter 内存占用过高。 Flutter 内存占用过高起因比较复杂,需另开一个主题能力说分明。简略总结下咱们调研的论断:Dart Heap 内存治理以及 Flutter Widget 设计综合导致业务内存较高,其最外围的问题引擎设计使开发者容易踩中内存透露。开发过程中,内存透露常见且难以定位,总结次要 2 点起因: Flutter 渲染三棵树的设计,以及 Dart 各种异步编程的特点,导致对象援用关系比拟绕,剖析艰难Dart “闭包”,“实例办法”可赋值传递,导致所在的类被办法上下文持有,不经意就会产生透露。典型例如注册一个 listener 没有反注册,导致 listener 所在的类对象透露开发者享受了 Flutter 开发的便利性,却人不知;鬼不觉中接受了内存透露的苦果。因而,咱们迫切需要一套高效的内存透露检测工具来解脱这种窘境。 盘点我理解到的几种内存透露检测计划: 监控 State 是否透露:针对 State 的透露检测。但 State 是 Flutter 内存透露中占比最大的对象吗?StatelessWidget 的对象也是能够援用很大内存的监控 Layer 个数:比照 正在应用,内存中的 Layer 个数来断定是否存在内存透露。计划对内存透露断定是否精确?Layer 对象离业务 Widget 太远,溯源太艰难Expando 弱援用透露断定:断定特定对象是否透露并返回援用链 。但咱们不晓得Flutter 中最应该监控的对象是哪个,哪个对象透露是次要问题?基于 Heap Snapshot 内存透露检测:比照不同两个工夫点的 Dart 虚拟机 Heap 对象的增长,以“class内存增量”,“对象内存个数” 2 个指标检测产生透露的可疑对象。这是个通用的解决方案,但要做到高效定位到透露对象(Image, Layer)才比拟有价值。目前“确定检测对象”和“检测机会”这 2 个问题都不好解决,所以还须要人工逐个排查确认,效率不高。总之,咱们感觉计划 1,2 逻辑上不够齐备,计划 3,4 效率有待进步。 更好的计划是? 参考 Android,LeakCanary 可能精确、高效检测 Activity 内存透露,解决内存透露的次要问题。那咱们能不能在 Flutter 中也实现一套这样的工具呢?这应该是一套更好的计划。 ...

November 17, 2021 · 4 min · jiezi

关于flutter:记InheritedWidget使用思考

记InheritedWidget应用思考InheritedWidget 是我的项目中必不可少的组件,用户数据共享。陈词滥调的Provider框架也是基于InheritedWidget实现的简介InheritedWidget组件是功能性组局,实现了由上向下共享数据的性能。即子组件通过BuildContext.dependOnInheritedWidgetOfExactType办法从父组件获取数据。 值得提一下,这种由上向下提供书共享数据的形式和Notification传递方向正好相同。两者相同点是:都是由子组件发动的。InheritedWidget是又子组件通过content向树上方查找数据,Notification是由子组件向上发动告诉。 特点子组件通过[BuildContext.dependOnInheritedWidgetOfExactType]办法查找对应最近的InheritedWidget并获取数据。InheritedWidget依据习惯或者协定,提供of静态方法,便于子组件获取数据。该办法并非肯定返回该继承的widget,也能够返回其余数据。调用of办法的组件,必须要在InheritedWidget内。如果在同一个widget中应用,能够通过Builder将须要应用的组件包裹起来。作用在应用中咱们发现,InheritedWidget作用是父组件提供数据,子组件能够由下往上查找对应的共享数据,这个是它直观的作用。 罕用的谬误更新数据形式setState: 咱们发现网上的有很多文章在介绍InheritedWidget的应用,并更新数据。然而这个只是体现了该组件的作用。绝大多数是在InheritedWidget组件中通过final申明共享数据。而后在父组件中通过setState强制刷新父组件,同时也刷新了InheritedWidget组件,当然其多层子组件都会跟着一起rebuild,造成了很大的非必要耗费。 如何去优化?InheritedWidget提供了数据的共享,防止了数据由上到下层层申明传递。咱们应用数据的中央也很明确。接下来要做的是,数据刷新后,让指定组件去更新。这个时候咱们就想到了ValueNotifier:InheritedWidget在共享数据的时候通过ValueNotifier包裹,子组件通过of办法获取的数据类型也是ValueNotifier,在应用的中央通过ValueListenableBuilder实现。 进一步思考在【老孟Flutter】源码剖析系列之InheritedWidget一文中提到了,批改of办法: dependOnInheritedWidgetOfExactTypegetElementForInheritedWidgetOfExactType<T>().widget 两者的区别:调用dependOnInheritedWidgetOfExactType() 和 getElementForInheritedWidgetOfExactType()的区别就是前者会注册依赖关系,而后者不会,所以在调用dependOnInheritedWidgetOfExactType()时,InheritedWidget和依赖它的子孙组件关系便实现了注册,之后当InheritedWidget发生变化时,就会更新依赖它的子孙组件,也就是会调这些子孙组件的didChangeDependencies()办法和build()办法。而当调用的是 getElementForInheritedWidgetOfExactType()时,因为没有注册依赖关系,所以之后当InheritedWidget发生变化时,就不会更新相应的子孙Widget。 @overrideT? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>( {Object? aspect}) {assert(_debugCheckStateIsActiveForAncestorLookup());final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T];// 多出局部if (ancestor != null) { assert(ancestor is InheritedElement); return dependOnInheritedElement(ancestor, aspect: aspect) as T;}_hadUnsatisfiedDependencies = true;return null;}@overrideInheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() {assert(_debugCheckStateIsActiveForAncestorLookup());final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T];return ancestor;}很显著批改为getElementForInheritedWidgetOfExactType<T>().widget,就会少一个非必要注册,也算是坏事。 进一步思考产生疑难既然通过了ValueNotifier和InheritedWidget联合,咱们通过批改ValueNotifier的value来扭转页面时,InheritedWidget组件没有从新构建并不会触发updateShouldNotify,也就是在应用数据的子组件中didChangeDependencies办法也不会因为value的扭转而调用。所以of办法具体用什么去实现,取决于具体业务设计。 文中的图片均借用于【老孟Flutter】源码剖析系列之InheritedWidget

November 12, 2021 · 1 min · jiezi

关于flutter:flutter数据共享系列随记

flutter数据共享系列——随记ProviderInheritedWidget 解决了数据共享问题。迎面也带来数据刷新导致的组件不必要更新问题。Provider基于InheritedWidget实现数据共享,数据更新,定向告诉组件更新等。 接下来咱们先从Provider应用开始切入,逐渐剖析Provider的实现,以及对组件的利用进行相熟。 就拿官网文档开始: 新建一个模型Counter :class Counter with ChangeNotifier { int _count = 0; int get count => _count; void increment() { _count++; notifyListeners(); }}在适合的地位初始化这里咱们抉择main办法: void main() { runApp( MultiProvider( providers: [ ChangeNotifierProvider(create: (_) => Counter()), ], child: const MyApp(), ), );}应用并批改数据class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const MaterialApp( home: MyHomePage(), ); }}class MyHomePage extends StatelessWidget { const MyHomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Example'), ), body: Center( child: Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: const <Widget>[ Text('You have pushed the button this many times:'), Extracted as a separate widget for performance optimization. As a separate widget, it will rebuild independently from [MyHomePage]. This is totally optional (and rarely needed). Similarly, we could also use [Consumer] or [Selector]. Count(), ], ), ), floatingActionButton: FloatingActionButton( key: const Key('increment_floatingActionButton'), Calls `context.read` instead of `context.watch` so that it does not rebuild when [Counter] changes. onPressed: () => context.read<Counter>().increment(), tooltip: 'Increment', child: const Icon(Icons.add), ), ); }}class Count extends StatelessWidget { const Count({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Text( Calls `context.watch` to make [Count] rebuild when [Counter] changes. '${context.watch<Counter>().count}', key: const Key('counterState'), style: Theme.of(context).textTheme.headline4); }}应用注意事项1. 共享数据定义为公有属性,提供get办法和update办法这样能够无效的爱护数据结构,对立批改入口和获取办法。 ...

November 12, 2021 · 2 min · jiezi

关于flutter:Flutter自定义时间轴timeline

组件在业务开发中常常会应用到timeline时间轴,来记录数据操作记录等,在这自己封装了一个绝对较通用的时间轴组件。 示例 参数参数类型必填阐明timelineListList是时间轴数据lineColorColor是时间轴轴线色彩heightdouble否时间轴右侧容器高度(默认80)titleStyleTextStyle否时间轴题目款式(已定义初始值 如无非凡款式无需传参)subtitleStyleTextStyle否时间轴副标题色彩 如果List数据不蕴含subtitle参数则不展现descriptionStyleTextStyle否时间轴形容款式leftContentbool否时候展现左侧工夫 true-展现 false-不展现 默认truetimelineList 参数类型阐明titleString题目数据subtitleString副标题数据descriptionString形容(如果remark不为空不展现)remarkString备注 展现成气泡模式dayString左侧工夫栏天 如 09-20timeString左侧工夫了工夫 如 11:40源码地址: https://github.com/gongchengh...

November 12, 2021 · 1 min · jiezi

关于flutter:AnyInspect-v010-一个使用-Flutter-Desktop-开发用于调试-Flutter-应用的工具

AnyInspect 是什么?AnyInspect 是一个用于调试您的 Flutter 利用的工具,应用 Dart / Flatter 编写。以后你能够应用 AnyInspect 来查看利用中的传出网络申请或查看 SharedPreferences 数据,将来你甚至能够在 AnyInspect 查看批改利用数据库的数据。 下载可在 公布 页面下载 AnyInspect 桌面端。 另请查看 网站 以理解其余装置办法。 疾速开始下载安装 AnyInspect 桌面端后,将 anyinspect 与配套插件集成到你的我的项目后从新运行你的利用。 你也能够间接装置集成示例来查看成果:anyinspect_integrate_example装置将此增加到我的项目的 pubspec.yaml 文件: dependencies: anyinspect: ^0.1.0 # 已反对的插件,请依据你的需要进行增加。 anyinspect_plugin_network: ^0.1.0 anyinspect_plugin_shared_preferences: ^0.1.0用法import 'package:anyinspect/anyinspect.dart';import 'package:anyinspect_plugin_network/anyinspect_plugin_network.dart';import 'package:anyinspect_plugin_shared_preferences/anyinspect_plugin_shared_preferences.dart';Future<void> main(List<String> args) async { AnyInspect anyInspect = AnyInspect.instance; anyInspect.addPlugin(AnyInspectPluginNetwork()); anyInspect.addPlugin(AnyInspectPluginSharedPreferences()); anyInspect.start(); // ...}显示辅助球辅助球能够显示与桌面端的连贯状态,并能够在断开连接后进行手动重连。 import 'package:anyinspect/anyinspect.dart';import 'package:flutter/material.dart';class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override _HomePageState createState() => _HomePageState();}class _HomePageState extends State<HomePage> { @override void initState() { super.initState(); // 在您的首页显示辅助球。 AnyInspect.instance.assistiveBall.show(context); } @override Widget build(BuildContext context) { // ... }}插件这些是可用的插件。 ...

November 11, 2021 · 1 min · jiezi

关于flutter:如何基于-React-Native-快速实现一个视频通话应用

明天,咱们将会一起开发一个蕴含 RTE (实时互动)场景的 Flutter 利用。 我的项目介绍靠自研开发蕴含实时互动性能的利用十分繁琐,你要解决保护服务器、负载平衡等难题,同时还要保障稳固的低提早。 那么,如何能力在较短的工夫内,将实时互动性能增加到 Flutter 利用中?你能够通过声网Agora SDK 来进行开发。在本教程中,我将带大家理解如何应用 Agora Flutter SDK 订阅多个频道的过程。(多频道是什么样场景呢?咱们稍后举些例子。) 开发环境网页拜访 Agora.io,注册一个Agora开发者账户。下载 Flutter SDK:https://docs.agora.io/cn/All/downloads已装置 VS Code 或 Android Studio对 Flutter 开发的根本理解为什么要退出多个频道?在进入正式开发之前,咱们先看看为什么有人或者说实时互动场景须要订阅多个频道。 退出多个频道的次要起因是能够同时跟踪多个群组的实时互动流动,或者同时与各个群组互动。各种应用场景包含线上的分组讨论室、多会议场景、期待室、流动会议等。 我的项目设置咱们先创立一个 Flutter 我的项目。关上你的终端,找到你的开发文件夹,而后输出以下内容。 flutter create agora_multi_channel_demo找到 pubspec.yaml,并在该文件中增加以下依赖项。 dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 agora_rtc_engine: ^3.2.1 permission_handler: ^5.1.0+2在增加包的时候要留神这边的缩进,否则可能会呈现谬误。 在你的我的项目文件夹中,运行以下命令来装置所有的依赖项: flutter pub get一旦咱们有了所有的依赖项,就能够创立文件构造了。找到 lib 文件夹,创立一个像这样的文件目录构造: 创立登录页面登录页面只需读取用户想要退出的两个频道即可。在本教程中,咱们只保留两个频道,但如果你想的话也能够退出更多的频道: import 'package:agora_multichannel_video/pages/lobby_page.dart';import 'package:flutter/material.dart';import 'package:permission_handler/permission_handler.dart';class LoginPage extends StatefulWidget { @override _LoginPageState createState() => _LoginPageState();}class _LoginPageState extends State<LoginPage> { final rteChannelNameController = TextEditingController(); final rtcChannelNameController = TextEditingController(); bool _validateError = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: Text('Agora Multi-Channel Demo'), elevation: 0, ), body: SafeArea( child: SingleChildScrollView( clipBehavior: Clip.antiAliasWithSaveLayer, physics: BouncingScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: <Widget>[ SizedBox( height: MediaQuery.of(context).size.height * 0.12, ), Center( child: Image( image: NetworkImage( 'https://www.agora.io/en/wp-content/uploads/2019/06/agoralightblue-1.png'), height: MediaQuery.of(context).size.height * 0.17, ), ), SizedBox( height: MediaQuery.of(context).size.height * 0.1, ), Container( width: MediaQuery.of(context).size.width * 0.8, child: TextFormField( controller: rteChannelNameController, decoration: InputDecoration( labelText: 'Broadcast channel Name', labelStyle: TextStyle(color: Colors.black54), errorText: _validateError ? 'Channel name is mandatory' : null, border: OutlineInputBorder( borderSide: BorderSide(color: Colors.blue, width: 2), borderRadius: BorderRadius.circular(20), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.black, width: 2), borderRadius: BorderRadius.circular(20), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.blue, width: 2), borderRadius: BorderRadius.circular(20), ), ), ), ), SizedBox( height: MediaQuery.of(context).size.height * 0.03, ), Container( width: MediaQuery.of(context).size.width * 0.8, child: TextFormField( controller: rtcChannelNameController, decoration: InputDecoration( labelText: 'RTC channel Name', labelStyle: TextStyle(color: Colors.black54), errorText: _validateError ? 'RTC Channel name is mandatory' : null, border: OutlineInputBorder( borderSide: BorderSide(color: Colors.blue, width: 2), borderRadius: BorderRadius.circular(20), ), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.black, width: 2), borderRadius: BorderRadius.circular(20), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.blue, width: 2), borderRadius: BorderRadius.circular(20), ), ), ), ), SizedBox(height: MediaQuery.of(context).size.height * 0.05), Container( width: MediaQuery.of(context).size.width * 0.35, child: MaterialButton( onPressed: onJoin, color: Colors.blueAccent, child: Padding( padding: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.01, vertical: MediaQuery.of(context).size.height * 0.02), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ Text( 'Join', style: TextStyle( color: Colors.white, fontWeight: FontWeight.bold), ), Icon( Icons.arrow_forward, color: Colors.white, ), ], ), ), ), ) ], ), ), ), ); } Future<void> onJoin() async { setState(() { rteChannelNameController.text.isEmpty && rtcChannelNameController.text.isEmpty ? _validateError = true : _validateError = false; }); await _handleCameraAndMic(Permission.camera); await _handleCameraAndMic(Permission.microphone); Navigator.push( context, MaterialPageRoute( builder: (context) => LobbyPage( rtcChannelName: rtcChannelNameController.text, rteChannelName: rteChannelNameController.text, ), ), ); } Future<void> _handleCameraAndMic(Permission permission) async { final status = await permission.request(); print(status); }}在胜利提交频道名称时,会触发 PermissionHandler(),这是一个来自内部包(permission_handler)的类,咱们将应用这个类来获取用户在调用过程中的摄像头和麦克风的权限。 ...

November 11, 2021 · 5 min · jiezi

关于flutter:dart系列之dart语言中的函数

简介函数是所有编程语言都有的内容,不论是面向对象还是面向过程,函数都是十分重要的一部分。dart中的函数和java中的函数有什么区别呢? dart作为一种面向对象的编程语言,它的函数也是一个对象,用Function来示意。先看下函数的定义: abstract class Function { external static apply(Function function, List<dynamic>? positionalArguments, [Map<Symbol, dynamic>? namedArguments]); int get hashCode; bool operator ==(Object other);}既然函数是一个对象,那么能够将函数赋值给对象,还能够将函数当做参数传递给其余的函数。 上面是一个简略的函数,由返回值,函数名称,参数和函数体来示意: bool isStudent(int age){ return age < 20; }只管dart倡议咱们指定函数的返回值类型,然而你也能够疏忽返回值: isStudent(int age){ return age < 20; }函数还有一个简写形式,如果函数体只有一条语句,那么能够应用=> 来代替括号: isStudent(int age) => age < 20;看起来更加简洁。 函数的参数dart中的函数参数有一般参数,也有命名参数。 一般参数很好了解,那么什么是命名参数呢? 命名参数就是给参数传递的时候起了一个名字,这样函数在调用的时候,能够指定参数的名字,来赋值。 看一个函数参数和命名参数的例子: bool calculator(int age , {int? size}){}能够这样调用: calculator(15,size:10);默认状况下命名参数是可选的,也就是说函数在调用的时候能够抉择是否传递可选的参数。 如果必须要传递某个参数,那么能够将其设置为required. 除了命名参数之外,dart还有可选的地位参数,就是将参数放在[]中,如下所示: String say(String from, String msg, [String? device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } return result;}下面的函数在调用的时候,能够只传入一般参数,也能够额定的传入可选的地位参数,如下: ...

November 10, 2021 · 1 min · jiezi

关于flutter:dart系列之dart语言中的内置类型

简介和所有的编程语言一样,dart有他内置的语言类型,这些内置类型都继承自Object,当然这些内置类型是dart语言的根底,只有把握了这些内置类型才可能在应用dart语言的时候得心应手。 明天就给大家解说一下dart语言的内置类型。 Null在dart中用null来示意空。那么null和Null有什么关系呢? Null是一个类,先看下Null的定义: class Null { factory Null._uninstantiable() { throw UnsupportedError('class Null cannot be instantiated'); } external int get hashCode; /** Returns the string `"null"`. */ String toString() => "null";}能够看到Null类型的string示意就是null。而相应的null是一个关键字,其对应的就是Null类。 数字dart中的数字对应的类是num,他有两个子类,别离是int和double。 int示意不大于64 bits的整数。因为dart能够运行在不同的平台中,所以不同平台示意的范畴也是不同的。 在原生平台,比方android或者IOS平台,int的范畴能够达到 -2^63 到 2^63 - 1。 然而在web环境中,可示意的范畴是-2^53 到 2^53 - 1. double相应的示意的是浮点类型。 对于数字来说,根本的运算操作符像是 +, -, / 和 *都是定义在num类中。当然还有其余一些惯例的操作符。 如果须要更加简单的运算,则能够应用dart:math库。 上面是几个数字应用的例子: int age =18;int number= 20;double money = 10.1;字符串字符串是常常会应用的一种类型。dart中字符串对应的类是String。也能够间接用字面量示意如下: var name ='jack';var site ="www.flydean.com";字符串能够用单引号也能够用双引号来示意。dart中字符串应用的是UTF-16编码。 dart中的字符串中,还能够带上变量值,他的格局是 ${expression}. ...

November 9, 2021 · 1 min · jiezi

关于flutter:如何用-Flutter开发一个直播应用

昨天,我在加入在线瑜伽课程时,才意识到我的日常流动中应用了这么多的视频直播 App--从商务会议到瑜伽课程,还有即兴演奏和电影之夜。对于大多数居家隔离的人来说,视频直播是靠近世界的最好形式。海量用户的观看和直播,也让“完满的流媒体 App”成为了新的市场诉求。 在这篇文章中,我将疏导你应用声网Agora Flutter SDK 开发本人的直播 App。你能够依照本人的需要来定制你的利用界面,同时还可能放弃最高的视频品质和简直感触不到的提早。 开发环境如果你是 Flutter 的老手,那么请拜访 Flutter 官网装置 Flutter。 在https://pub.dev/搜寻“Agora”,下载声网Agora Flutter SDK v3.2.1在https://pub.dev/搜寻“Agora”,声网Agora Flutter RTM SDK v0.9.14VS Code 或其余 IDE声网Agora 开发者账户,请拜访 Agora.io 注册我的项目设置咱们先创立一个 Flutter 我的项目。关上你的终端,导航到你开发用的文件夹,而后输出以下内容。 flutter create agora_live_streaming导航到你的 pubspec.yaml 文件,在该文件中,增加以下依赖项: dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.0 permission_handler: ^5.1.0+2 agora_rtc_engine: ^3.2.1 agora_rtm: ^0.9.14在增加文件压缩包的时候,要留神缩进,免得出错。 你的我的项目文件夹中,运行以下命令来装置所有的依赖项: flutter pub get一旦咱们有了所有的依赖项,咱们就能够创立文件构造了。导航到 lib 文件夹,并创立一个像这样的文件构造。 创立主页面首先,我创立了一个简略的登录表单,须要输出三个信息:用户名、频道名称和用户角色(观众或主播)。你能够依据本人的须要来定制这个界面。 class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> { final _username = TextEditingController(); final _channelName = TextEditingController(); bool _isBroadcaster = false; String check = ''; @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: true, body: Center( child: SingleChildScrollView( physics: NeverScrollableScrollPhysics(), child: Stack( children: <Widget>[ Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(30.0), child: Image.network( 'https://www.agora.io/en/wp-content/uploads/2019/06/agoralightblue-1.png', scale: 1.5, ), ), Container( width: MediaQuery.of(context).size.width * 0.85, height: MediaQuery.of(context).size.height * 0.2, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ TextFormField( controller: _username, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), borderSide: BorderSide(color: Colors.grey), ), hintText: 'Username', ), ), TextFormField( controller: _channelName, decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(20), borderSide: BorderSide(color: Colors.grey), ), hintText: 'Channel Name', ), ), ], ), ), Container( width: MediaQuery.of(context).size.width * 0.65, padding: EdgeInsets.symmetric(vertical: 10), child: SwitchListTile( title: _isBroadcaster ? Text('Broadcaster') : Text('Audience'), value: _isBroadcaster, activeColor: Color.fromRGBO(45, 156, 215, 1), secondary: _isBroadcaster ? Icon( Icons.account_circle, color: Color.fromRGBO(45, 156, 215, 1), ) : Icon(Icons.account_circle), onChanged: (value) { setState(() { _isBroadcaster = value; print(_isBroadcaster); }); }), ), Padding( padding: const EdgeInsets.symmetric(vertical: 25), child: Container( width: MediaQuery.of(context).size.width * 0.85, decoration: BoxDecoration( color: Colors.blue, borderRadius: BorderRadius.circular(20)), child: MaterialButton( onPressed: onJoin, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'Join ', style: TextStyle( color: Colors.white, letterSpacing: 1, fontWeight: FontWeight.bold, fontSize: 20), ), Icon( Icons.arrow_forward, color: Colors.white, ) ], ), ), ), ), Text( check, style: TextStyle(color: Colors.red), ) ], ), ), ], ), ), )); }}这样就会创立一个相似于这样的用户界面: ...

November 8, 2021 · 7 min · jiezi

关于flutter:Flutter-6-个建议改善你的代码结构

注释1. 将 init 操作与 main 函数拆散,使其更加清晰 2. 你能够简略地治理这样的 GetX 路由,而不须要任何麻烦用法Get.toNamed(Routes.login);怎么做 3. 你也能够在一个中央治理你的款式格调用法// S stands for StylesS.colors.redS.textStyles.f10MediumS.shadows.softShadow怎么做 4. 像 boss 一样治理你的资源用法// R stands for Resources// AnimationsR.anims.loading// SVG imagesR.icons.logo// `magesR.images.怎么做 5. 集中管理你的常量用法// C stands for ConstantsC.titleC.namesC.descp怎么做 6. 建设你的工具类 utils,咱们在一个中央应用所有的工夫用法Utils.formatDate(date,locale);Utils.formatters.onlyTwoDecimalDigits;Utils.show.dialog();怎么做 © 猫哥 https://ducafecat.tech/https://github.com/ducafecat微信群 ducafecatb 站 https://space.bilibili.com/40...

November 8, 2021 · 1 min · jiezi

关于flutter:Flutter-保护你的APP数据安全

原文https://medium.com/@mohammadE...参考https://www.guardsquare.com/e...https://www.freecodecamp.org/...https://www.freecodecamp.org/...注释 目前,大多数应用程序都蕴含领取或存储一些重要的集体数据,这减少了数据被攻击者利用或裸露的危险。 在这篇文章中,我将议论最无效的做法,以尽量减少 Flutter 应用程序中任何安全漏洞的危险,并设置尽可能多的路障,以任何攻击者的形式。当然,这并不能保障你的应用程序是 100% 平安的。 让咱们开始爱护通信层 https://www.guardsquare.com/e... 当攻击者锁定一个应用程序时,首先要做的事件之一就是查看他们是否 能拦挡在应用程序和服务器后端之间传递的任何数据 。 1- 采纳高度加密:您能够通过应用 SSL 和 TLS 等协定来实现这一点,这些协定很容易增加到您的代码中,并且很难斗争。 如果您正在解决特地敏感的数据,您甚至可能须要更进一步,在应用程序中构建一个相似 vpn 的解决方案。 2- 限度网络流量将网络流量或连贯限度到不平安端点的一种办法是显式地将域名列为白名单。 要做到这一点,在 flutter 应用程序,咱们须要为每个平台做一些步骤: android : go to the android folder and create this file under 进入 android 文件夹,创立上面的文件 res/xml/network_security_config.xml而后复制这个并将其增加到创立的 xml 文件中: <?xml version="1.0" encoding="utf-8"?><network-security-config> <domain-config> <domain includeSubdomains="true">YOURDOMAIN.com</domain> <trust-anchors> <certificates src="@raw/YOURCERTIFICATE"/> </trust-anchors> </domain-config></network-security-config>for ios: add this to the info.plist file: 把这个增加到 info.plist 文件: <key>NSAppTransportSecurity</key><dict> <key>NSAllowsArbitraryLoads</key> <false/> <key>NSExceptionDomains</key> <dict> <key>YOURDOMAIN.com</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict></dict>而后用你的服务器域名替换 YOURDOMAIN.com 。 ...

November 5, 2021 · 2 min · jiezi

关于flutter:端开发技术解密Flutter响应式布局

Flutter是一个跨平台的利用开发框架,反对各种屏幕大小的设施,它能够在智能手表这样的小设施上运行,也能够在电视这样的大设施上运行。应用雷同的代码来适应不同的屏幕大小和像素密度是一个挑战。 Flutter响应式布局的设计没有硬性的规定。在本文中,我将向您展现在设计响应式布局时能够遵循的一些办法。 在应用Flutter构建响应式布局之前,我想阐明一下Android和iOS是如何解决不同屏幕大小的布局的。 1. Android的办法为了解决不同的屏幕尺寸和像素密度,在Android中应用了以下概念: 1.1 ConstraintLayoutAndroid UI设计中引入的一个革命性的货色是ConstraintLayout。它能够用于创立灵便的、响应性强的UI设计,以适应不同的屏幕大小和尺寸。它容许您依据与布局中其余视图的空间关系来指定每个视图的地位和大小。 但这并不能解决大型设施的问题,在大型设施中,拉伸或只是调整UI组件的大小并不是利用屏幕面积的最优雅的形式。在屏幕面积很小的智能手表,调整组件以适应屏幕大小可能会导致奇怪的UI。 1.2 Alternative layouts要解决上述问题,您能够为不同大小的设施应用alternative layouts。例如,你能够在平板电脑等设施上应用分屏视图来提供良好的用户体验,并明智地应用大屏幕。 在Android中,你能够为不同的屏幕大小定义不同的布局文件,Android框架会依据设施的屏幕大小主动解决这些布局之间的切换。 1.3 Fragments应用Fragment,你能够将你的UI逻辑提取到独自的组件中,这样当你为大屏幕尺寸设计多窗格布局时,你不用独自定义逻辑。您能够重用为每个片段定义的Fragment。 1.4 Vector graphicsVector graphics应用XML创立图像来定义门路和色彩,而不是应用像素位图。它能够缩放到任何大小。在Android中,你能够应用VectorDrawable来绘制任何类型的插图,比方图标。 2. iOS的办法iOS用于定义响应式布局的形式如下 2.1 Auto LayoutAuto Layout可用于构建自适应界面,您能够在其中定义用于控制应用程序内容的规定(称为束缚)。 当检测到某些环境变动(称为特色)时,“Auto Layout”会依据指定的约束条件主动从新调整布局。 2.2 Size classesSize类的特点是会依据其大小主动调配给内容区域。 iOS 会依据内容区域的Size类别动静地进行布局调整。在iPad上,size类也实用。 2.3 一些UI 组件还有一些其余的UI嘴贱你能够用来在iOS上构建响应式UI,像UIStackView, UIViewController,和UISplitViewController。 3. Flutter是如何自适应的即便你不是Android或iOS的开发者,到目前为止,你应该曾经理解了这些平台是如何解决响应式布局的。 在Android中,要在单个屏幕上显示多个UI视图,请应用Fragments,它们相似于可在应用程序的Activity中运行的可重用组件。 您能够在一个Activity中运行多个Fragment,然而不能在一个应用程序中同时运行多个Activity。 在iOS中,为了管制多个视图控制器,应用了UISplitViewController,它在分层界面中治理子视图控制器。 当初咱们来到Flutter Flutter引入了widget的概念。它们像积木一样拼凑在一起构建应用程序画面。 记住,在Flutter中,每个屏幕和整个应用程序也是一个widget! widget实质上是可重用的,因而在Flutter中构建响应式布局时,您不须要学习任何其余概念。 3.1 Flutter的响应式概念正如我后面所说的,我将探讨开发响应式布局所需的重要概念,而后你来抉择应用什么样的形式在你的APP上实现响应式布局。 3.1.1 MediaQuery你能够应用MediaQuery来检索屏幕的大小(宽度/高度)和方向(纵向/横向)。 上面是例子 class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { Size screenSize = MediaQuery.of(context).size; Orientation orientation = MediaQuery.of(context).orientation; return Scaffold( body: Container( color: CustomColors.android, child: Center( child: Text( 'View\n\n' + '[MediaQuery width]: ${screenSize.width.toStringAsFixed(2)}\n\n' + '[MediaQuery orientation]: $orientation', style: TextStyle(color: Colors.white, fontSize: 18), ), ), ), ); }} ...

November 4, 2021 · 4 min · jiezi

关于flutter:端开发技术FLutter开发即时通讯

1. 即时通讯简述即时通讯是端开发工作中常见的需要,本篇文章以作者工作中应用FLutter开发社交软件即时通讯需要为背景,形容一下即时通讯功能设计的要点。 2. 重要概念即时通讯须要前后端配合,约定音讯格局与音讯内容。本次IM客户端需要开发应用了公司已有的基于Socket.io搭建的后盾,下文形容波及到的一些概念。 2.1 WebSocket协定WebSocket是一种在单个TCP连贯上进行全双工通信的协定。WebSocket协定与传统的HTTP协定的次要区别为,WebSocket协定容许服务端被动向客户端推送数据,而传统的HTTP协定服务器只有在客户端被动申请之后能力向客户端发送数据。在没有WebSocket之前,即时通讯大部分采纳长轮询形式。 2.2 Socket.io和WebSocket的区别Socket.io不是WebSocket,它只是将WebSocket和轮询 (Polling)机制以及其它的实时通信形式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。也就是说,WebSocket仅仅是Socket.io实现即时通信的一个子集。因而WebSocket客户端连贯不上Socket.io服务端,当然Socket.io客户端也连贯不上WebSocket服务端。 2.3 服务端socket音讯了解了服务端socket音讯也就了解了服务器端的即时通讯逻辑,服务器收回的socket音讯能够分为两种: 服务器被动收回的音讯: 例如,社交软件中的A用户给B用户收回了音讯,服务器在收到A用户的音讯后,通过socket链接,将A用户的音讯转发给B用户,B用户客户端接管到的音讯就属于服务器被动收回的。其余比拟常见的场景例如直播软件中,全平台用户都会收到的礼物音讯播送。 服务器在接管到客户端音讯后的返回音讯: 例如,长链接心跳机制,客户端向服务器发送ping音讯,服务器在胜利承受客户端的ping音讯后返回的pong音讯就属于服务器的返回音讯。其余常见的场景如社交软件中A用户给B用户收回了音讯,服务器在收到A用户的音讯后,给A客户端返回一条音讯,供A客户端理解音讯的发送状态,判断发送是否胜利。大部分场景,服务器在接管到客户端被动收回的音讯之后都须要返回一条音讯。 3. 客户端实现流程几个设计客户端即时通讯的重点。 3.1 心跳机制所谓心跳就是客户端收回ping音讯,服务器胜利收到后返回pong音讯。当客户端一段时间内不在发送ping音讯,视为客户端断开,服务器就会被动敞开socket链接。当客户端发送ping音讯,服务器一段时间内没有返回pong音讯,视为服务器断开,客户端就会启动重连机制。 3.2 重连机制重连机制为客户端从新发动连贯,常见的重连条件如下: 客户端发送ping音讯,服务器一段时间内没有返回pong。客户端网络断开。服务器被动断开连接。客户端被动连贯失败。当呈现极其状况(客户端断网)时,频繁的重连可能会导致资源的节约,能够设置一段时间内的最大重连次数,当重连超过肯定次数时,休眠一段时间。 3.3 音讯发送流程将音讯存储到本地数据库,发送状态设为期待。发送socket音讯。接管到服务器返回的socket音讯后,将本地数据库期待状态的音讯改为胜利。注意事项: 将音讯存储到本地数据库时须要生成一个id存入数据库,同时传给服务器,当收到音讯时依据id判断更新本地数据库的哪一条音讯。 3.4 音讯接管流程 3.5 其余相干聊天页音讯的排序:在查问本地数据库时应用order by按工夫排序。音讯列表:也举荐做本地存储,当收到音讯的时候须要先判断本地音讯列表是否有以后音讯用户的对话框,如果没有就先插入,有就更新。音讯列表的保护就不开展说了,感兴趣能够看代码。图片语音音讯:将图片和语言先上传到专门的服务器上(各种专门的云存储服务器),sokcet音讯和本地存储传递的是云服务器上的URL。多人聊天(群聊):与单人聊天逻辑基本一致,区别位本地数据库须要增加一个会话ID字段,关上一个群就查问对应会话ID的数据。聊天音讯不再是谁发给谁,而是在哪个群聊下。4. 客户端Flutter代码把局部代码贴上来,残缺我的项目在作者的github上。 4.1 心跳机制 heart() { pingTimer = Timer.periodic(Duration(seconds: 30), (data) { if (pingWaitTime >= 60) { socket.connect(); pingWaitTime = 0; pingWaitTimer!.cancel(); ping(); } if (!pingWaitFlag) ping(); }); } ping() { debugPrint("ping"); String pingData = '{"type":"ping","payload":{"front":true},"msg_id":${DateTime.now().millisecondsSinceEpoch}}'; socket.emit("message", pingData); pingWaitFlag = true; pingWaitTime = 0; pingWaitTimer = Timer.periodic(Duration(seconds: 1), (data) { pingWaitTime++; print(data.hashCode); if (pingWaitTime % 10 == 0) debugPrint(pingWaitTime.toString()); }); } //pong if (socketMessage.type == PONG && socketMessage.code == 1000) { pingWaitFlag = false; pingWaitTimer!.cancel(); pingWaitTime = 0; }4.2 本地数据库设计数据库表的设计是比拟重要的,了解了数据库设计,读代码也就无压力了。 ...

November 4, 2021 · 1 min · jiezi

关于flutter:开源项目5种技术编写的7个demo工程

android/ios/flutter/angular/java web 5种技术编写的7个demo工程,有点用,能够看看,github地址,https://github.com/ThinkerJac...。 android_demo1.我的项目简介《第一行代码》第二版书中示例demo,工夫过来比拟久,有一些API变动,本人入手写了一遍。 2.环境简介语言:java 1.8 依赖库:详见android_demo/app/build.gradle下的dependencies 3.我的项目截图 4.开发流程与代码逻辑简述关上Android Studio配置安卓开发环境MainActivity为入口文件,批改其中的跳转页面,体验不同的demo5.技术筹备java根底语法《第一行代码》书籍第二版安卓开发官网6.总结因为在学习之前有java根底,间接浏览此书没有遇到什么艰难,一些API的变动搜索引擎就解决了。作为一名Flutter工程师,播种了一些安卓零碎特有的常识,如服务,内容提提供器,播送,告诉,申请权限,调试安卓程序,打包构建等等。FLutter作为依附于native零碎的技术,相熟native零碎的个性还是很有比拟必要的,尽管大部分常识FLutter工作中用不到,但感觉播种还是蛮大的。在往年的学习打算完结后,后续可能把native零碎的学习作为首要指标。 android_web1.我的项目简介本人写的一个登录demo,调用了实在的接口,次要就是想模仿一下实在的android开发流程。 2.环境简介语言:java 1.8 依赖库:详见android_demo/app/build.gradle下的dependencies 3.我的项目截图 4.开发流程与代码逻辑简述关上Android Studio配置安卓开发环境编写xml布局文件在Activity中获取页面控件,给按钮增加监听事件将输入框中的元素通过网络申请发送给服务器,拿到返回后果后将json序列化为Java对象。5.技术筹备java根底语法Android布局技术okhttpGSON Gson gson = new Gson();JsonBean data = gson.fromJson(responseData, JsonBean.class);6.总结一个简略的小APP,蕴含了挪动开发中必备的环节,网络申请,获取页面元素,json序列化。官网文档+搜索引擎+一点教训解决工作中百分之九十五的问题。。 angular_demo1.我的项目简介应用Angular框架和TypeScript编写的前端我的项目。次要蕴含一些web开发中罕用组件的展现。 2.环境简介语言:TypeScript 框架版本:Angular CLI:11.2.6 包管理工具:Node:14.16.0 3.我的项目截图 4.开发流程与代码逻辑简述搭建开发环境创立工程,装置组件库NG-ZORRO和ng-bootstrap在我的项目中引入所须要的具体组件在html文件中绘制布局,在ts文件中编写逻辑5.技术筹备TS语法Angular基础知识组件库文档NG-ZORRO和ng-bootstrap6.总结很简略的开源我的项目,过后写这个次要是为了相熟一下angular组件。作为github上本人惟一的前端我的项目,我感觉很没程度,连最起码流程页面都没有一个,不过本人自身前端程度也不高,也不打算长期在这方面倒退,打算之内还有其余的事件,只能承受这种不完满了。 在职业生涯的初期,本人始终在写Angular,从Angular.js到Angular7,8,11,因为对前端没有一点的趣味,唉,工作之外的工夫都去学java写后盾了,始终也没有深刻理解angular,就是CRUD,然而这种工作和私下学习离开的学习形式对我来说成果很不好,导致JAVA服务器端开发和前端开发都没有深刻,其实本人当初也面临着这样的问题,工作两年,java web,angualr,flutter,android,iOS,除却FLutter有一些积攒外,其余的技术都是勉强应酬工作,环境和集体认知导致的吧,本人这只有广度没有深度的技术栈,从资本主义的角度来看,专精一门的工人生产力更高,也就是所谓的大厂螺丝钉。进步本人的生产力,就是让本人更值钱,接下来的一年也会朝着专精一门的方向倒退,除却计算机基础知识的学习外,在flutter和android上进步本人的技术深度。争取在工作三年之际给本人一个称心的答案。 尽管本人始终苦于没有技术深度,然而这种技术广度也让本人对整个产品的开发流程更加理解,其实很多技术常识都是能够复用的,像本篇文章中介绍的框架Angular的响应式编程,在FLutter中也同样实用;还有端开发的对立流程,发送申请,获取数据,更新UI;就是后端和前端的某些常识也是能够通用的,在写后盾的过程中学习SQL常识,在端开发的本地存储上一样实用;面向对象还能在脚本开发中发挥作用。还有程序架构mvc,mvp,mvvm之类,很多很多吧。 得益于这两年来的自学,不夸大的说,让本人造就出了较强的学习能力,学习能力其实是很形象的,首先有学习的激情,同样学习激情的两个人,在学习过程中的速度和成果,就能够了解为学习能力。这两年间本人的大脑里曾经有了一张图谱,在面对新常识的时候,会敏锐的发现哪些常识和之前学的常识相似,并将他们关联起来,哪些是须要重点学习的新概念,哪些是不太重要的常识。大脑其实是很懈怠的,碰到了解不了的货色他就会扩散你的注意力,让你去做一些不须要动脑的事件,我把这些事件称之为精力垃圾。学习分两种,向之前提过的将常识与原来学习过的货色分割起来不算真正意义上的学习,叫温习。只有哪些你了解不了的概念,大脑不想让你持续学上来的常识,才是无效的学习。面对这样的状况,就是用意志力和大脑反抗,我就是要弄懂,一遍不懂就反复看,看懂为止。意志力又是一个新概念了,我感觉很多平凡的文学作品都加强了我的意志力,让我敢于面对生存,活着就挺难了。 没有文档的开源我的项目相当于没有灵魂,本人专门腾出一些工夫,给这些我的项目赋予灵魂,为测试不同的我的项目配置了很多环境。益处就是本人的开源我的项目写的没那么多,工作量尚可,本人的记忆也还不错,我的项目的一些流程和细节都还能想的起来。还没有灵魂的我的项目不多了,争取这周搞完,当前写我的项目写完之后肯定要写一份文档,这种堆积起来一次补齐的形式太累了。这两年总是在迷茫和换工作中度过,很多本人想做的事件都被筹备面试耽搁了,这份工作无论如何也要做一年多,把本人想做的货色,想学的常识井井有条的实现,也算对得起本人。 flutter_demo1.我的项目简介flutter APP。 我的项目分五个文件夹: 动画组件工作中用到或是一些其余乏味的组件布局相干的组件学习FLutter编写的练习或是测试代码工具类,前面会独自写成一个我的项目2.环境简介语言:Dart fLutter版本:Channel master, 2.3.0-17.0.pre.414 3.我的项目截图 4.开发流程与代码逻辑简述组件比拟多就不一一介绍了5.技术筹备Dart根底FLutter API6.总结这个我的项目保护是比拟多的,首页上展现的只有动画和一些乏味的组件,能够下载体验一下,看看有没有感兴趣的性能。这个我的项目有独自的地址,目前这个demo工程只是一些测试代码。 IOS_Demo1.我的项目简介学习ios写的小demo,比拟系统,看到感兴趣的知识点就本人入手试一下,没有什么下载价值。 2.环境简介语言:Swift 5.4 UI框架:UIKit 3.我的项目截图 4.开发流程与代码逻辑简述更多的应用了storyboard拖拽控件的开发方式,简略体验了一下。5.技术筹备Swift根底语法UIKit应用6.总结找的不少教程都不写纯代码,都是storyboard拖拽控件联合代码,不太喜爱这种形式. 写在开端因为更换了电脑,两个java相干的工程须要从新搭建环境补齐文档,临时不打算更新了,感兴趣的网上轻易搜几篇技术文章就能搭。 后续如果本人想写点后盾的话,就棘手把这两个readme补齐。

November 4, 2021 · 1 min · jiezi

关于flutter:开源项目FLutter开发录音APP

Flutter录音APP一个录音小工具,github地址,https://github.com/ThinkerJac...。 1.语言环境Flutter SDK : stable 2.0.6 Dart SDK: stable 2.12.3 2.我的项目截图 3.开源软件包flutter_sound: ^8.1.9 #录音+转MP3path_provider: ^2.0.1 #获取文件门路dio: ^4.0.0 #发送网络申请permission_handler: ^8.1.3 #申请录音权限4.开发流程简述检测录音权限是否开启,未开启会在APP内申请权限,将用户输出的ID传递到歌曲列表画面。歌曲列表画面调用两个接口,一个接口获取以后账户录过多少首歌曲,一个接口获取歌曲列表,滑动列表为ListView,申请谬误时弹出POP框。点击歌曲进入到录音页面。录音页面展现的数据均为列表画面通过构造方法传入,调用flutter_sound包录音,录音完结后将acc转换为MP3,点击上传调用接口,通过FormData上传本地的MP3文件,申请谬误弹出POP。5.我的项目总结技术上来说没有什么难点,没有引入过多的第三方软件包,网络申请,路由跳转,页面间传值都没有进行额定的封装。产品的原型也比较简单,没有设计图。比拟大的播种是相熟了一下FLutter我的项目android和IOS的打包。 android打包,命令:flutter build apk --split-per-abi,默认打包形式就是release,flutter build apk打进去的包特地大,因为多种架构模式的安卓包都打在一起了,加上--split-per-abi会把不同架构的包离开打,"armeabi-v7a", "arm64-v8a"是比拟支流的,安卓也能够独自关上我的项目中的android文件夹,应用原生的形式进行打包,在app/build.gradle增加ndk配置,将支流的CPU架构打到一个包里,有两个中央须要特地留神,一是打包时signature中的V1和V2都须要勾选上,为了适配低版本安卓,二是app/build.gradle中的minSdkVersion决定了兼容的安卓版本,21适配安卓5.0。 IOS打包,IOS打包比较复杂,举荐一篇文章,文章有些内容有点过期,不过大部分流程都笼罩到了,简略形容一下就是在Xcode中配置好,而后flutter build ipa ,生成一个Runner.xcarchive文件,双击xcarchive文件始终Next生成IPA。如果不公布到app store,须要先拿到用户的UDID,增加到Devices,而后依照官网举荐的形式获取证书Certificates,Certificates就是给开发用的电脑装的,而后生成Profiles选中Devices和Certificates。在打包时选中生成的Profiles。如果公布到app store就不须要Profiles,选中Signing选项卡里的Automatically manage signing就能够了。Certificates是必须要装置的。 第二版晋升了一下录音的音质,将采样率改成了96000,将比特率改成了256000。

November 4, 2021 · 1 min · jiezi

关于flutter:算法算法的时间空间复杂度

1. 预先分析法毛病:不同的数据规模,不同的机器下算法运行的工夫不同,无奈做到计算运行工夫 2. 事先分析法2.1 大O工夫复杂度渐进工夫复杂度 随着n的增长,程序运行工夫追随n变动的趋势 2.1.1 几个准则去掉常数项 2(n^2) =n^2 一段代码取工夫复杂度最高的 test(n) { //工夫复杂度n^3 for(int i = 0; i < n ; i++){ for(int i = 0; i < n ; i++){ for(int i = 0; i < n ; i++){ print(n); } } } //工夫复杂度n^2 for(int i = 0; i < n ; i++){ for(int i = 0; i < n ; i++){ print(n); } } //工夫复杂度n for(int i = 0; i < n ; i++){ print(n); }}这段代码的工夫复杂度为n^3+n^2+n ...

November 4, 2021 · 1 min · jiezi

关于flutter:杂谈什么是Google-Fuchsia

Google正在开发一个新的操作系统:借助Fuchsia OS,该技术小组放弃了Linux体系结构,转而依附自行开发的微内核Zircon。Fuchsia 不仅能够代替台式机操作系统Chrome操作系统,而且能够代替专为挪动设备设计的Android。只管事实上,Android在当今市场上简直是无可比拟的。 Google Fuchsia是将来的操作系统吗?咱们认真钻研了该我的项目。 什么是Google Fuchsia ?Fuchsia 不仅是红色和蓝色之间的一种色彩,还是Google自2016年以来始终在公众背后开发的模块化,基于权限的实时操作系统的名称。该零碎应用C,C ++, Dart,Go和Rust,并在古代64位Intel ARM处理器上运行。 事实 实时操作系统(RTOS)是一种可能响应事件并立刻或在预约工夫内提供处理结果的操作系统。 Fuchsia OS的源代码已取得开源许可证(包含BSD,MIT和Apache许可证),并且能够由Google公共Git存储库中的任何人查看和下载。这是无关该项目标综合文档。 依据文档,Fuchsia OS同样实用于智能手机,平板电脑,笔记本电脑和台式计算机。自2017年5月起,Armadillo已成为具备图形用户界面的触摸优化用户界面(UI)。谷歌正在为Fuchsia OS开发一个桌面UI,题目为Capybara。从那以后,有传言称Google正在致力代替简直无可比拟的Android。 Fuchsia OS如何工作?Google在开发Fuchsia OS方面开拓了新天地。能够说,该公司从过来的谬误中汲取了教训,尤其是在更新和批改Android和Chrome OS的局限性和问题方面。与已建设的Google操作系统的次要区别:Fuchsia OS从头到尾都是模块化的。这不仅反映在模块化零碎体系结构中,而且反映在对应用程序是什么的全新了解中。 模块化利用设计Google Fuchsia基于模块化设计,突破了应用程序的概念。软件单元称为软件包。软件包是一个被选中的文件—包含元数据、清单文件和可执行元素。后者在Google术语中称为组件。 Fuchsia 组件最靠近咱们明天所说的应用程序。每个组件执行特定工作,并且能够与其余组件组合以编程一个更简单的应用程序。组件由清单文件以及相干的代码组成。组件始终在本人的沙箱中运行,通过名称空间拜访对象,并通过导出目录公布它们。Fuchsia OS专一于两种类型的组件:模块(modules )和代理(agents)。 agents组件在后盾工作,并为其余组件提供服务。agents由另一个组件或零碎调用-例如,响应某些触发(例如推送告诉或其余屏幕解决)。 modules是具备用户界面的组件,这些组件在前台执行,对用户可见。操作系统中的每个模块都是为特定工作而设计的,并进行了相应的标记,以便能够在须要时主动对其进行拜访。这是应用模块的性能实现的,能够应用所谓的动词和名词来形容。 每个模块都包含一个verbs 列表,示意模块能够执行的工作,以及一个nouns 列表,示意正在应用的实体。依据谷歌术语,实体包含作为结构化数据对象存在的任何惟一可辨认的人、地点、事物、事件或概念,这些数据对象能够被援用和检索、出现、操作或共享。 因而,在理论中,应用实时操作系统Fuchsia的形式如下:用户执行操作后,Fuchsia OS会主动为该工作确定适当的模块。所需的动作被翻译成动词和名词的组合。而后,零碎检索所有反对所需动词的模块的列表,并在下一步中依据还能够解决所需名词的模块进行过滤。 相干的模块能够分组到所谓的stories中。stories依据以后的需要组合不同的动作和工作,使用户可能依据本人的想法和需要组装简单的应用程序。 概要 =借助Fuchsia OS的模块化应用程序概念,Google将重点从应用程序转移到动作和内容。Fuchsia 的工作由所谓的stories中的一组组件来解决,而不是以后应用的应用程序的经典操作系统,该组件通过模块拜访以后所需的资源。 下图阐明了Fuchsia OS利用程序开发背地的模块化概念。 Fuchsia OS的利用程序开发基于模块化构造。 模块化零碎架构Fuchsia OS的零碎架构也基于模块化办法。操作系统由四个或多或少的独立级别组成,每个级别都有其本人的工作:Zircon,Garnet,Peridot和Topaz。 ZirconZircon(以前为Magenta)是新的Google操作系统的根底,但严格来说,它不是Fuchsia OS的一部分,也能够与其余操作系统一起应用。 Zircon蕴含Fuchsia OS的内核,设施管理器,最外围的第一层设施驱动程序以及底层零碎库(如libc和launchpad)。此外,Zircon还提供FIDL(Fuchsia 接口定义语言),这是一种用于过程间通信的协定。FIDL是独立于编程语言的,然而与风行的编程语言(例如C,C ++,Dart,Go和Rust)具备分割。 作为Fuchsia OS的根底,Zircon提供了对后续级别的硬件拜访,在共享硬件资源上创立了软件形象,并充当了低级软件开发的平台。Zircon是Project Little Kernel(LK)的后果,该我的项目充当Android的疏导程序。 GarnetGarnet是基于Zircon的第一款针对Fuchsia 的零碎层。提供了设施级别的各种零碎服务以及网络,媒体和图形服务,例如,用于软件装置,系统管理以及与其余零碎的通信。Garnet蕴含图形渲染器Escher,程序包治理和更新零碎Amber以及文本和代码编辑器Xi。 PeridotPeridot是Fuchsia OS的操作系统级别,依据以后用户要求在其上治理和编译模块化应用程序(请参见上文)。Peridot的外围成分是Ledger和Maxwell。 Ledger:Ledger是基于云的存储系统(分布式存储系统),它为每个Fuchsia组件(模块或代理)提供独自的数据存储。这在不同设施之间同步。这使用户能够在以后Fuchsia 的设施上持续停留在其余Fuchsia 的设施上的地位。Maxwell:通过Maxwell,Google在Fuchsia OS中集成了一个组件,该组件将给用户提供了人工智能。就像Fuchsia 一样,Maxwell具备模块化设计。AI零碎由一系列代理组成,这些代理剖析用户的行为及其所应用的内容,在后盾确定适合的信息,并将倡议转发给操作系统-例如,应加载哪些模块或故事以适宜用户在特定工夫的行为。Google语言助手也是AI组件的一部分,该组件将在Fuchsia我的项目的框架内以代码Kronk的模式进一步开发。 留神 到目前为止,Kronk是Fuchsia OS惟一未作为开源我的项目开发的组件。 ...

November 4, 2021 · 1 min · jiezi

关于flutter:杂谈程序人生我的大学

我的大学 2015.09 - 2019.07自己是大连某三本学校的学生,大一大二的时候没怎么学过习,就在第一学期的C语言课程上认真听了课,听到指针的时候就了解不下来了,从那以后看待专业课的态度就是能过就行。大一大二很快就过来了,十分重要的数据结构一次课都没听过,汗颜。到了大三,在房地产公司兼职,因为干的工夫长,工作比拟致力,从发传单到管他人发传单,过后感觉还好,基本没有从事计算机行业的打算,正是过后兼职的经验让本人对工作的辛苦有了正确的意识。到了大三下学期,因为抱着计算机专业肯定要干计算机的童稚想法,也感觉转行干房地产会很丢人,每天在里面风吹日晒很累,工资也不高,不如当程序员每天坐在办公室里轻松。楼主自己还有日光炎,就是夏天一晒就会脖子前面起货色,简略的掂量之下,筹备学习编程。 过后学校的课程还没有全副完结,有PHP开发这门课,刚巧学校不报我的项目大四就不能实习,就本人申报了一个网站我的项目。最开始的时候比拟迷茫,因为除了循环根本对编程语言没有任何理解,本人在博客上搜寻了PHP网站开发学习路线,趁着当当满一百减五十,买了很多书。就看了一本《PHP从入门到精通》,最开始是在慕课网上找的PHP教程,教程看完,大略两周工夫吧,把《PHP从入门到精通》看了差不多,书上的大部分例子都操作过,又在慕课网的教程上学习了HTML/CSS,JS,过后大一的SQL/SERVER课程还听了听,数据库简略的增删改查还都理解,打算参照老师给的我的项目开始做本人的网站。老师的我的项目是THINKPHP5框架,在慕课网上找了一个乌云龙老师的THINKPHP5教程,这个教程讲的特地好,很快了解了THINKPHP5的应用。当初还记得的就是过后学到的MVC设计模式,学THINKPHP框架的同学十分举荐这个课程,分高低两局部,几天的工夫就可以看完。 那时的本人除去每天上课,基本上都泡在图书馆。看书,看教程,尽管学习效率不是很高,然而比拟致力,基础知识大略学了一个月左右的工夫。尽管不是很深刻,但大体的网站开发须要的技能都有所理解。这时开始做网站了,过后做我的项目是参照学校老师录得视频,视频比拟短但各个步骤都有讲,同学们如果自学也能够本人去上网找我的项目视频,照着人家做就能够了。首先确定好了本人网站的需要,搭好了环境,没想到在集成后盾模板HUI-ADMIN的时候就呈现了问题,因为这个模板里的工夫模块和THINKPHP框架不兼容,会始终报错,过后疯狂的找博客,因为本人基本看不懂框架源码报的是什么错,英语根底也比拟差,怎么找都找不到,那个早晨真的是十分艰巨,网站刚刚开始就遇到了解决不了的谬误,弄到中午切实弄不进去就睡觉了。第二天加了HUI模板的官网群,群里的一位热心老哥通知了我问题的谬误所在,改了谬误编码就开始了。 最后照着老师的我的项目代码写增删改查,多半是复制粘贴,把办法里的数据库字段改掉就能够了。不会的时候还能问一问和我一起去图书馆的大佬同学,在咱们学校算是很优良了,然而他不太会教,他只是帮忙解决问题,没通知我为什么。有一天中午,本人忽然就想通了数据在前台到后盾的传输过程,从页面获取,传到办法,传到数据库。这时候根本的谬误本人都能改了,也是这时候开始有点收缩了,感觉本人贼NB,在网上搜寻了一段他人的搜寻分页代码,粘贴到本人的网站上,后盾实现了大部分,过后大三下如同还有一个月,图书馆也不去了,偶然欠缺欠缺本人的后盾,这个学期就这样完结了。 放寒假回家,过后在编程语言抉择上十分困惑,不晓得PHP写网站后盾好还是JAVA好,问了问本人的几个程序员亲戚,都是叔叔哥哥辈的,都说JAVA好找工作,范畴也比拟大。职位最高的程序员前辈,说“你学PHP能力值几个钱,语言要坚韧不拔的抉择JAVA”,在这里不评估这句话对不对,因为自己也没有什么教训,然而起初找工作的时候的确也是JAVA招的多,不得不抵赖,深深地被职位最高的程序员前辈影响了,决定转学JAVA,其实说是转学,PHP本人原来也没学明确,哈哈。在淘宝上买了一套黑马程序员javaweb45期视频,如同是叫这个名吧,买过两次,第一次是32期,当初两家店都黄了,这个资源能够在百度网盘上搜到,基本不必买,评论中有49期全套视频链接,放假回家开始看JAVASE根底,大略两个月的课吧,每天看的也不是特地用心。打算好了大四上学期找实习岗位,这个时间段作者自己始终沉迷在做了PHP网站的收缩之中,学习也不是特地致力,看的是黑马32期老师讲的根底视频,当初回想起来老师讲的的确是很好,很多看起来非常复杂的语言个性,都能听明确,然而JAVASE自身要比PHP的根底语法难一些。过后在不停的犹豫转学JAVA对不对的自我狐疑下,把根底视频看完了,其实好多没记住。 大四上学期2018年9月,投简历找实习,大连招收根底较差的学生实习的企业很少,加上本人自身学的也不精,数据结构和算法更是无所不通,除了一些打着招聘名义的培训机构,基本没人要,过后十分犹豫要不要去培训机构,几个月吧,要交两万。过后面试进去,本人痛哭流涕,感觉本人节约了大学的所有工夫,最初找个实习工作还要交钱培训,感觉很对不起父母,“PS:这只是自己的想法,不对培训机构有任何敌意”,犹豫再三还是没有去,本人又开始了在图书馆看培训班视频的日子,被事实狠狠的打了两拳,一下子就晓得本人的实在程度了,起初面试别的公司的时候,基本不提工资,有钱就行啊。 图书馆学习的某一天,原来投过简历的公司给我打了电话,让我面试,在再三确认不是培训机构之后,我去了。过后先是做口试题,有日语题,逻辑题,根底题,因为日语零根底,只做了逻辑题和根底题,逻辑题没什么讲的,根底题如同就JAVA两道,SQL两道,JAVA就问了8种根本数据类型,和面向对象,SQL问了外连贯和罕用聚合函数。过后只写上了JAVA题,SQL程度大家也都晓得,一个没做上,口试题交上去,本人做在会议室等,闲的无聊,百度搜了搜方才没做上的SQL常识,大略理解了一下。随后面试,面试官是两个部长和总经理,公司大略一百多人,基本上就全副领导层了,谁会想到他一上来问的就是方才我口试题空着的SQL,因为刚刚查过,简略扯了几句,就混过去了。由此可见,不会的常识随时百度有如许重要,前面面试的大哥又问了问我的我的项目,这还是第一次面试问我我的项目,因为之前面试的公司不是培训,就是要间接干活的外包,一听见有人问我的项目我很冲动,讲了讲,尽管我的项目没有什么NB的性能,也是我本人辛苦学习的成绩,到当初我的简历上还只有这一个我的项目,哈哈,过后状态比拟好,面试通过了,间接就签了实习协定,因为本人自控力较差,早上常常起不来,想着每天上个班束缚一下本人,学习工夫也能长点,开始了实习生涯。 实习的这家公司是对日外包,操作系统都是日文,和我原来想的相差很远,然而因为本人程度较低,想着有个公司就先将就一下吧,每天学学日语,练练SQL,等着两个月的培训期一过就能够去项目组了,然而最好受的是不晓得后续可能会干什么方向,都是随机调配的,有嵌入式,C++,.NET,javaee,每天很好受,想着本人PHP转学JAVA难道又要学别的语言?第四天就辞职了,日语和不确定的方向,让我十分好受,感觉在节约我的工夫,十月一日之后,靠着同学亲戚的帮忙,进了沈阳的某家公司JAVAWEB岗位实习。。。 /这之后的经验很多,作者有点困了,午睡之后还要学习,哪天有工夫再分享。/ 那是18年国庆节放假完结的第三天,带上了货色来到了新的公司报道,入职手续办完,开始了沈阳实习生存,第一周比拟迷茫,不晓得每天须要做些什么,和四周共事也没怎么交换过,每天看一看公司的业务,菜鸟教程上的oracle,公司业务很简单,本着实习为了学习技术的想法,对业务也不是很上心,在网上找了一套oracle查问练习题做了做,数据库根本的常识也都把握了,每天朝九晚五,下了班回到宿舍打两把游戏,第一周这样完结了,第二周本人思考了一下这样不行啊,实习的导师就给我一个工作,让我看公司现有我的项目的代码,于是又掏出了本人的培训班视频,在同学那里学会了1.3倍速看视频,大略不到两周的工夫,把培训的视频比拟认真的看完了,后续本人看书学习JAVA的时候,有不少知识点在看视频的时候都了解了,黑马32期根底班,讲的很好,零根底学习无压力,羞愧,一个月的视频,本人总共看了四个月才看完,学到这里,本人JAVAse的程度算是有了很大的提高,去网上搜寻JAVA面试题,局部题目都能了解了。 Java根底学完过后比拟迷茫,是把培训班的全套视频都看完,还是做一做公司我的项目的简略模块,因为公司的框架是本人封装的,学了培训班后续的框架视频,对写公司的我的项目帮忙也不大,于是乎又咸鱼了两天,这时候我的大哥呈现了,本文接下来的学习资源简直全部都是他分享给我的,最开始加微信是原来的同学介绍的,和我说有什么校招问题征询他,因为原来对校招简直没有任何理解,加了微信好友有一段时间,也没怎么交换过,过后正是在后续的学习抉择上比拟困惑,就本人上网查了查校招,才发现校招都是互联网公司,而且工资很高,好吧最开始就是因为工资高才被吸引的,就问了问大哥校招都须要学习些什么,过后大哥给我分享了四个方面的常识,“JAVA根底,计算机网络,数据库,数据结构与算法”自此以后正式踏入了筹备春招的路。 第一次和大哥交换的时候感觉还比拟轻松,齐全没有意识到本人间隔校招的技术要求有多远。当初回忆和大哥最后的交换中,印象最深的就是大哥说,“学习肯定要深刻”,这就是本人过来学习经验中最大的问题,学什么都是浅尝辄止,会用就行,基本不会去想着理解原理,写到这里作者想检查一下本人,因为最近比拟焦虑,借着写这篇文章安稳一下心态,为后续的春招常识学习做好筹备,认真想了想我如同没有什么毛病……(2021年来看这就是我过后最大的毛病,间歇性收缩),学习的意义到底是什么,记不得在哪里看到过这样一段话,分享给大家“咱们对这个世界,晓得得还切实太少。有数的未知突围着咱们,才使人生保留爆发的乐趣。当哪一天,世界上的所有都能明确解释了,这个世界也就变得非常无聊。人生,就会成为一种简略的轨迹,一种爽朗的反复”,只有每天的提高才是最稳固的生存,每天的你都比昨天更好,想想就是一件特地NB的事件,春招进大公司对于我来说的确十分艰难,原来上大学没学的常识都要补回来 ,然而在2016年看科比的纪录片时,记住了片中的这样一句话“如果我默然承受失败的事实,那就如同给本人宣判了死刑”。/文章先分享到这里,因为后续的学习十分多,目前没有什么非常明显的阶段造成果,无奈对学习资源做出牢靠的总结,等到有肯定的阶段性成绩之后再分享给大家/于2018-11-12 对我来说,回顾本人的过来是很苦楚的,再次续写这篇文章曾经是2020-12-01,眨眼之间两年过来了,18年末产生的所有宛如还在眼前,最开始的学习是很认真的,每天刻苦的看《疯狂JAVA讲义》和《大话数据结构》,播种很大,对JAVA语言的了解从原来的只理解语法到把握了一些原理,根本的数据结构也都把握了,这段时间学习的货色到明天也还在受害,每天早九晚九,上班回到公司宿舍还要学一会,闲暇工夫刷一刷牛客网上的JAVA口试题,在那段时间领导如同基本没有给我安顿任何写代码的工作,实习期间对公司的惟一奉献就是几十个excel的复制粘贴,这样的生存继续了一段时间,在沈阳凛冽的天气和宿舍简直不热的暖气的作用下,我感冒了,一开始认为只是小感冒,没有在意,寻思和原来看待感冒一样,挺一挺就过来了,前面开始疯狂的咳嗽,早晚尤为重大,咳嗽到中午无奈睡觉,早晨没睡觉白天也起不来去下班,就开始长期的销假,这个时候开始白天就没有再学习了,曾经有点记不清是在感冒之前就曾经没有再持续学习,还是感冒后才没有持续学习,是我的大脑不违心承受本人放弃了学习的事实,把感冒和放弃学习放在一起了?总之在这之后根本没有再学习了,前面去医院看了一下是支气管炎,开了药,感冒好了还是留下了早晚咳嗽的后遗症,(有病千万别挺着,这是血的教训),那个时候班也不怎么上了,根本每天销假,白天窝在宿舍疯狂玩手机游戏,过年回到老家哈尔滨,咳嗽还是没好,还有减轻的趋势,美其名曰在家养病,就是玩游戏,学习春招曾经抛在脑后了,(其实明天来看过后的本人,也没法要求本人更多了),过完年又回去接着实习,上一天班请四天假,哈哈哈,之后回到学校写毕业论文,和同学一起high,一眨眼就是六月份了,我毕业了。 过后的我对找工作有着迷之自信,实习的时候代码都没写过,却感觉写代码也就那么回事,哈哈哈,在那个时候我对java的框架基本是无所不通,只会一点JAVA根底,(才刚刚意识到本人大学毕业时的程度有多差),六月份开始投简历,找JAVA相干的岗位,很偶合,面试的第一家公司就过了,去了先是做一套口试题,一些代码题和逻辑题,之后面试跟面试官轻易唠了几句,就收到了offer,过后对找工作基本没有什么概念,感觉待遇差不多就行,工资4.9k,13薪,公司提供收费宿舍,班车,有加班费,于是抱着保个底的想法签订了三方协定,之后和同学一起约定去成都找工作,到了重庆玩了一周,到了成都玩了一个月,找工作?早都抛在脑后了,于是到了七月份,在签订三方的公司入职了。

November 4, 2021 · 1 min · jiezi

关于flutter:杂谈程序人生第一份工作

第一份工作 2019.07 - 2020.10入职的流程基本上都差不多,过后对公司的业务,工作内容齐全不理解,其实这家公司是一家人力外包公司,人力外包就是公司没有任何业务,只是负责把程序员招进来,再差遣到须要人的公司,相当于你是A公司的员工,平时在B公司下班,可能B公司找A公司要人,一个人是月薪1w,到你手里就只有5k了,A公司次要靠这个盈利,我所在的人力外包和一般的人力外包略有区别,我要去下班的B公司是A公司的母公司,两家公司还在一个楼里,不像一些其余的人力外包,哪里有工作就把程序员派到哪,可能都不是一个城市。因为是全资子公司,在B公司下班没有感觉到和B公司的员工有什么区别,公司的食堂,上下班的班车,节日补贴,年终奖的规范都是一样的,接下来再介绍一下下班的B公司,B公司是一家外包公司,次要是对日业务,这家公司的活是怎么接的呢,首先日本政府有一个我的项目,去公开招标,这时日本的一家公司竞标胜利了,然而他们不本人做,他把这个活承包给单干的中国公司,这个活到中国公司相当于是第三手,利润当然是层层递加的,日本公司拿掉大头,剩下小头给到中国公司,对日外包公司次要靠虚报人数和工时来赚钱,可能这个我的项目只须要三个人就能实现,管日本公司要十个人的钱,这个利润就进去了,这也就造成了公司加班重大,呈现一人同时干多个我的项目的状况,毕竟你干的越多,公司赚的越多吗,我就更惨了,到我这里又被人力外包公司拿去一层,20世纪的杨白劳,哈哈,开个玩笑。 进入到人力外包公司,先是进行面试,进了公司还要进行面试,是的,你没听错,B公司的部门要招人,就会通过面试筛选A公司的人,因为这家公司对应届生的要求不是那么太高,顺利通过了面试,开始本人的工作生涯,最开始进去的半个月没有项目组须要老手,项目组退出老手须要造就,须要节约项目组的工夫,教完能有多少产出也不肯定,最开始的半个月还是在看书,疯狂java讲义,半个月之后终于有项目组要人了,胜利进入了项目组,项目组是一个对日我的项目,是做一家日本守业公司的跨国电商网站,应用angular开发电商网站的前端,PC端网站和mobile端网站,过后本人很懵,面试的明明是JAVA,怎么进来干上前端了,其实这是外包公司比拟常见的状况,想做什么技术的工作不是本人决定的,什么我的项目缺人就被派到哪里去,‘我是反动的一块砖,哪里须要哪里搬’,一开始本人对干前端十分冲突,本人是比拟想在一个方向上深刻的,不想频繁的更换语言,于是工作之余又投递了一些java岗位,接到了面试的音讯,面试完之后,毫无疑问,被面试官吊打,这下终于意识到本人的实在程度了,老老实实在当初这家干前端。 刚毕业的本人对工作还是比拟有激情,尽管本人会的不多,然而有一些JS根底,在我的项目中被动学习,不会就问,定期写一些博客,记录本人工作中学到的常识和遇到的问题,逐步适应了这份前端工作,这个电商我的项目的动态html都是客户提供的,平时次要的工作就是写一些前端的业务,数据处理,逻辑判断,加班也蛮多的,过后本人对java始终有执念,感觉本人肯定要干java才行,于是工作之余又自学java,过后没有本人写我的项目,都是学一些实践上的常识,起初来看,成果十分不好,平时学的常识如果不能反哺到工作中,就算过后学会了,不写一些文章总结或者在工作中应用尝试,是很难记住的。 因为是刚刚毕业,心态还没有做好转变,看待工作没有一个正确的态度,最重大的问题是过后本人基本受不了他人的批评,受到批评总是感觉他人是SB,本人做的全都对,起初看一个语言类节目,嘉宾说的一句话印象粗浅,其实一个年纪比你大,生存经验比你丰盛,在这个行业积淀很多年的人批评你,就像是在给你送钱,当然恶意中伤人的除外,过后看完感触很深,自此之后,面对批评都是虚心接受加上感激,本人也会定时的反思本人,咱们常说面对SB,不要和他争执,对他说'just do it,this good for you',换个视角来看,你的领导发现了你的问题,感觉你是个SB,他没有束之高阁,指出你的问题,这是一种馈赠,过后本人的另一个问题是工作态度的问题,过后实习上一天班劳动四天留下的坏毛病,过后基本不了解工作,当初了解工作其实就是出卖工夫,你的老板领取你工资,相当于他花钱买了你的工夫,让你为他工作,你不认真对待工作能够说是你的诚信方面有问题,拿了人家的钱不给人家好好干活。过后对技术的意识还很全面,最开始想干java,工作是前端,感觉本人毫无播种,或者工作反复的写业务,感觉没有什么晋升,其实咱们要学会用成长型思维看问题,(举荐一本好书《一生成长》)一份工作会给一个人带来很多方面的成长,可能是硬实力也可能是软实力,技术上的,项目管理,为人处世,商业模式,其实能学到的货色很多,别埋怨工作垃圾,其实是你没有发现这份工作的可取之处,写这篇文章也不齐全是技术上的记录,本人成为程序员之后的一些其余方面的思考也写在外面,心愿能给刚入行的年轻人一些帮忙,把本人设想成一块水灵灵的海绵,不要对本人设限,无论是技术上还是其余的方面,到了社会上你能学到的很多,放弃虚心,虚心学习(stay hungry,stay foolish)。 又灌一大口鸡汤。其实工作和学习相辅相成,对我来说,是效率很高的一种学习,岂但能加深记忆,还能让本人工作效率越来越高,干什么学什么,其实语言选择没那么重要,你只有在支流或者将来看起来不错的的语言里抉择一个就能够了,选语言就像买股票,谁都想买个天天涨停的股票,谁能保障本人的股票天天涨停,同理,也没有经久不衰的语言,抉择一个方向,认真钻研,成为这门语言使用者里的前百分之二十,不愁一份差不多的工作,持续聊回工作,日子一天天过来,始终就是angular写前端,随着逐步适应,工作也变的反复,工作中写一份清晰易读的文档是十分有用的,就拿装环境来说,如果你不写文档,项目组每新加一个小伙伴,你就要帮他装个环境,写个好文档,你的工夫就省进去了,环境搭建,框架应用,标准,跟领导汇报,都须要写文档的能力,大略是19年7月份到12月份,本人平时下了班都是学java,根本全忘了,相当于白学,这两头还自学了一些算法,感觉学算法挺好,能够锤炼本人的逻辑思维能力,逻辑思维能力是一种永久性的晋升,从一个长期主义者的角度来看这是十分值得的投资。(PS:在这两头找到了当初的女朋友,办了张健身卡练了练),19年加入工作最大的播种是心态上的,从一个学生转变为一个职场人士,其次技术上接触了残缺的商业我的项目,真正理解到编程这份工作的内容。尽管工资不高,也能自力更生了,挺好。 转眼间就到了2020年,2020年工作上第一个事件就是换了项目组,这也是外包公司我集体不太喜爱的一点,想在一个方向上钻研很难,可能这个我的项目是JS,下个我的项目就是C#,因为项目组人员变动,换到了一个前端组,用JQuery写前端,一开始是先用html和bootstrap写动态页面,写着写着就到了过年,而后回家劳动,回家过年的工夫正是疫情第一波暴发,封城,没能回去下班,在家待到了3月份,在家期间本人看了下培训班的JAVA视频,把握了SSM框架,过年回去接着下班,又换项目组了,换到了一个java项目组,是旧我的项目革新,将原有我的项目的struts框架换为springmvc,这个我的项目真的是很无聊,每天都在复制粘贴,简直毫无技术可言,本人写了个小脚本就把活干了。有一点益处就是不必加班,头一次感触到按时上班的感觉,下了班打打游戏,感觉美滋滋,尽管学不到技术很焦虑,然而上班回去玩玩游戏也挺高兴,就这样到了6月份。 到了6月份,之前跨国电商我的项目的经理找到我,跟我说原来的我的项目要应用Flutter技术开发APP,问我有没有趣味回到之前的项目组学习Flutter,过后尽管本人也不理解Flutter技术,然而目前所在的JAVA我的项目真是什么也学不到,也不能这么说,见识到了日本人深厚的文档功力,文档写的十分具体,也理解到了残缺的我的项目流程,理解了一些之前没有经验的测试阶段,顺带学了下JSP和EL表达式,其实像对日外包公司,大部分都是这种无聊的工作。顺带提几句19年的事件,过后年会的时候,公司领导颁发优秀员工,跟我同时进入项目组的一个小伙伴拿到了这个奖,2000块钱一个奖状,奖尽管不大,然而深深的刺激到了我,大家都是一样工作,为什么她有我没有,论编程能力,我比她强一百倍,好吧有点吹牛逼,不过过后感到很不均衡,我默默把这件事件消化掉了,可能是因为一开始工作态度的起因吧,人真是经验一些挫折才会成长,世界是多元的,并不是以谁为外围,你只须要把本人的事件做好就能够了。 回到过后,我许可了原来的项目经理,回到之前的项目组应用Flutter技术开发APP,过后公司没有应用Flutter技术开发过APP,大家的终点都一样,这对我来说是个机会,在学习了一段时间Flutter技术之后,我逐步对Flutter技术产生了趣味,工作之外本人回去看Flutter相干的书,过后入门的一本书是《Flutter实战》,因为工作态度改善很大,加之之前的对日JAVA我的项目,让我逐步有了一些好的编程习惯,还有本人平时也在学习Flutter,逐步成为了项目组的外围,这时项目经理交给我一个开发之外的工作,就是负责解决其余我的项目成员的难题,这个兼职让我成长的很快,Flutter程度直线回升,本人在写APP的时候开发了一些业务组件,UI组件,介绍给项目组其余成员,大大提高了大家的效率,非常感谢项目经理,其实在工作中的成长和领导的造就有很大关系,领导信赖你,将一些外围业务和解决难题的工作交给你,这是十分难得的成长机会,举荐大家在工作的时候有这样的机会肯定要把握住,5月份开始学习Flutter,写过的需要越来越多,技术一直晋升,更难能可贵的是找到了本人的趣味所在,至多写Flutter时还是挺开心的,我的项目经理是一个四十岁的中年男人,小孩上初中,可能家庭压力比拟大,是部门里出了名的加班狂,我很认可这个领导,因为他总说真话,说真话其实也是我本人的一个准则,因为说谎是要付出代价的,你撒一个慌,你要说很多的慌来圆之前的慌,说真话的老本是最低的,这篇文章齐全没有虚构成分,都是集体的实在经验。到了10月份部门领导又要给我换组了,我感到很苦楚,决定换工作了,找Flutter相干的工作。

November 4, 2021 · 1 min · jiezi

关于flutter:端开发技术5个高效的Flutter开发工具

1. 你是否须要更好,更简洁的日志?当你在开发Flutter应用程序时,难以了解的日志是一个大问题,因为没有疾速的办法来依据问题的重大水平过滤你的日志。抛出异样或记录一条简略的调试音讯?他们看起来都一样。 如果你的Flutter app须要更好的日志零碎,Logger 软件包相对是个好货色。 Logger包地址:https://pub.dev/packages/logger 它受到Java分级日志的启发,容许您向日志增加级别。 日志级别,目前有: logger.v("Add more detailed debug messages, " "can contain sensitive information, never enable it in production");logger.d("Fine grained information to debug an application");logger.i("Track the flow of the application");logger.w("A potential but expected problem");logger.e("A real failure that may impact the application state");因为某些起因,另外一个特地的是 logger.wtf("WTF logs??")不仅如此,你还能够晃动你的设施来查看屏幕上的日志。(PS:须要导入logger_flutter包) 2. API还没有从后端筹备好,或者基本没有API ?应用程序靠本人硬编数据?如果你还在艰巨的coding,全是本人硬编数据因为后盾没有筹备好他们的API或者基本没有任何API,如果你依然心愿UI有意义,您能够应用faker包——Jesper Hakansson为应用程序生成有意义的数据。 受Python包faker和Ruby包ffaker的启发,这个包能够提供各种类型的数据,从虚伪的人名到虚伪的日期,甚至是随机的虚伪url。 只需创立一个简略的对象,像这样- var faker = new Faker();上面是应用faker对象的例子 faker.date.month();faker.conference.name();faker.company.position();faker.lorem.sentences(8);faker.internet.httpsUrl();faker.currency.name();faker.sport.name()在这个包下还有更多品种的数据可用,这是本人硬编数据的一个很好的替代品,当我的项目变得更简单时,本人硬编数据是很难替换的。 faker包地址:https://pub.dev/packages/fake... 3. 当API返回的数据结构简单,你须要疾速构建model?尽管我在2018年曾经分享过这篇解析简单JSON的文章,在明天它依然十分风行。 https://medium.com/flutter-co... 值得一提的是,这篇文章是对Dart解析json的一个很好的实践回顾,但我不倡议在构建理论简单我的项目时进行手动解析。 为什么不倡议? .手动操作必定要花很长时间。 .而且你更容易犯错误。 ...

November 4, 2021 · 1 min · jiezi

关于flutter:操作系统计算机硬件简介md

1. 简介从概念上讲,一台计算机能够形象为下图的模型 CPU,内存以及I/O设施都由一条系统总线连接起来并通过总线与其余设施通信 2. CPUCPU是计算机的大脑,它从内存中取出指令并执行。 2.1 CPU的工作流程从内存中取出指令,对取出的指令进行解码,执行,CPU就是始终一直的反复这个过程。 图1.1CPU工作流程2.2 超标量CPU流水线作业效率不高,于是就引入了超标量CPU 超标量CPU是这样工作的,多个取值和解码同时进行,取值解码实现后的指令会进入缓冲区,缓冲区对应多个执行单元,每当缓冲区中有指令且有闲暇的执行单元时,就会从缓冲区取出指令进入执行单元执行. 图1.2超标量CPU工作流程2.3 内核态和用户态少数CPU多有两种模式,内核态和用户态 在内核态运行时,CPU能够执行指令集的每一条指令,应用硬件的全副性能 在用户态运行时,CPU只能执行指令集的一个子集和拜访所有性能的一个本人 在台式机和服务器上,操作系统在内核态运行。在大多数嵌入式零碎中,一部分操作系统在内核态运行,其余部分在用户态运行 3. 存储器3.1 存储器分为四个档次寄存器 高速缓存 内存 硬盘 图2.1存储器的四层3.2 寄存器寄存器存在于CPU中,拜访和CPU一样快,没有时延 3.3 高速缓存罕用的高速缓存行搁置在CPU外部或十分靠近CPU的地位 3.3.1 高速缓存命中当程序须要读取一个字时,查看所须要的字是否在高速缓存中,如果在高速缓存中,称为高速缓存命中 如果高速缓存未命中,就要通过总线,把拜访申请传递到内存,这带来了访问速度的降落 PS:缓存 大量的资源存在于计算机存储器的某一处,其中一小部分资源会被频繁的用到,把频繁用的资源放到比大量资源更高层次的存储器中,这就是缓存。 计算机在读取文件时,将硬盘中频繁用的文件放入内存中,这就是缓存的利用。 应用缓存时咱们须要思考几个问题 1)何时把资源放入缓存中 2)把资源放在存储器的哪一层上 3)在缓存满了时,把什么内容从缓存中移走 4)移走的内容又该放到何处 3.3.2 内存内存通常成为随机拜访存储器(RAM),速度比磁盘快,程序先进入这里执行,内存具备断电数据隐没的个性。 PS:闪存 速度介于内存和磁盘间,断电后数据不隐没 3.4 磁盘3.4.1 磁盘工作流程像是老式的唱片机,一个又一个重叠起的圆盘,每个圆盘上配有一个指针,当从磁盘读取数据时指针一直旋转,读取一段环形区域,这段环形区域叫做磁道。 图2.2 磁盘的工作流程咱们常讲硬盘的转速,多少MB每秒,从磁盘的工作流程上咱们能够理解到,磁盘的转速就是磁盘臂旋转的速度 3.4.2 固态硬盘固态硬盘和一般磁盘不是同一种工作形式,固态硬盘其实是一种闪存 3.4.3 虚拟内存计算机的虚拟内存机制就是将磁盘中须要重复读取的内容放到内存中,放慢计算机的速度,也是一种缓存的利用 4. I/O设施I/O设施分为两个局部 设施控制器和设施自身 4.1 设施控制器设施控制器是插在电路板上的一块芯片或一组芯片,他是操作系统和设施之间的桥梁,配合操作系统操作设施,操作系统对它发成命令,它对操作系统的命令进行简单的转换,管制设施。 图3.1设施控制器4.2 设施自身硬盘,键盘,鼠标,显示器等等 设施自身有一个绝对简略的标准化接口,比方创立的SATA硬盘,SATA就是设施的接口名 4.3 设施驱动程序操作系统如何操作设施控制器呢,这个答案就是在操作系统上装置设施控制程序,设施控制程序负责与控制器对话,收回命令,承受响应。 ...

November 4, 2021 · 1 min · jiezi

关于flutter:这一次解决Flutter-Dialog的各种痛点

前言Q:你毕生中闻过最臭的货色,是什么? A:我那早已腐烂的梦。 兄弟萌!!!我又来了! 这次,我能自信的对大家说:我终于给大家带了一个,能真正帮忙大家解决诸多坑比场景的pub包! 将之前的flutter_smart_dialog,在放弃api稳固的根底上,进行了各种抓头重构,解决了一系列问题 当初,我终于能够说:它当初是一个简洁,弱小,侵入性极低的pub包! 对于侵入性问题 之前为了解决返回敞开弹窗,应用了一个很不优雅的解决办法,导致侵入性有点高这真是让我坐立不安,如芒刺背,如鲠在喉,这个问题终于搞定了!同时,我在pub包外部设计了一个弹窗栈,能主动移除栈顶弹窗,也能够定点移除栈内标记的弹窗。 问题应用零碎弹窗存在一系列坑,来和各位探讨探讨 必须传BuildContext 在一些场景必须多做一些传参工作,蛋痛但不难的问题loading弹窗 应用零碎弹窗做loading弹窗,必定遇到过这个坑比问题 loading封装在网络库外面:申请网络时加载loading,手贱按了返回按钮,敞开了loading而后申请完结后发现:特么我的页面怎么被关了!!!零碎弹窗就是一个路由页面,关闭系统就是用pop办法,这很容易误关失常页面 当然必定有解决办法,路由监听的中央解决,此处就不细表了某页面弹出了多个零碎Dialog,很难定点敞开某个非栈顶弹窗 蛋蛋,这是路由入栈出栈机制导致的,了解的同时也一样要吐槽零碎Dialog,点击事件无奈穿透暗色背景 这个坑比问题,我是真没辙思考下面列举了一些比拟常见的问题,最重大的问题,应该就是loading的问题 loading是个超高频应用的弹窗,敞开loading弹窗的办法,同时也能敞开失常应用的页面,自身就是一个隐患本菜狗不具备大厂大佬们魔改flutter的能力,菜则思变,我只能从其它方向切入,寻求解决方案零碎的Page就是基于Overlay去实现的,咱们也要骚起来,从Overlay动手 这次,我要一次性帮各位解决:toast音讯,loading弹窗,以及更弱小的自定义dialog! 疾速上手初始化引入(最新版本请点击pub查看):pub,github,click me to experience itdependencies: flutter_smart_dialog: ^3.0.0初始化形式一:强力举荐配置更加简洁void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return GetMaterialApp( initialRoute: RouteConfig.main, getPages: RouteConfig.getPages, // here navigatorObservers: [FlutterSmartDialog.observer], // here builder: FlutterSmartDialog.init(), ); }}初始化形式二:兼容老版本❤老版本初始化形式依然无效,区别是:须要在就加载MaterialApp之前,调用下FlutterSmartDialog.monitor()void main() => runApp(MyApp());class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { // here FlutterSmartDialog.monitor(); return MaterialApp( home: SmartDialogPage(), // here navigatorObservers: [FlutterSmartDialog.observer], /// here builder: (BuildContext context, Widget? child) { return FlutterSmartDialog(child: child); }, ); }}功败垂成下面俩种初始化形式,任选一种即可;而后,就能够残缺应用本库的所有性能了 ...

November 3, 2021 · 5 min · jiezi

关于flutter:Flutter-下载文件操作

原文https://medium.com/halkbank-m...代码https://github.com/deremakif/... 参考https://pub.dev/packages/path...https://pub.dev/packages/flut...https://pub.dev/packages/flowderhttps://pub.dev/packages/open...https://pub.dev/packages/perc...注释明天我要写一篇对于 flowder package 的文章。我用它从服务器上下载文件。有很多办法能够做到这一点,而且还有更受欢迎的软件包如 flutter_downloader 。但我更喜爱 flowder 软件包,因为它的实现很简略。 首先,如果下载文件夹不存在,咱们应该创立它。要做到这一点,咱们须要导入 path_provider package。并在当前页的 initState() 中调用 initPlatformState 办法。 Future<void> initPlatformState() async { _setPath(); if (!mounted) return;}void _setPath() async { Directory _path = await getApplicationDocumentsDirectory(); String _localPath = _path.path + Platform.pathSeparator + 'Download'; final savedDir = Directory(_localPath); bool hasExisted = await savedDir.exists(); if (!hasExisted) { savedDir.create(); } path = _localPath;}当初,咱们有下载文件夹来保留文件。包的下载办法须要两个参数: URL 和选项。您能够依据须要自定义选项。 ElevatedButton( onPressed: () async { options = DownloaderUtils( progressCallback: (current, total) { final progress = (current / total) * 100; print('Downloading: $progress'); }, file: File('$path/loremipsum.pdf'), progress: ProgressImplementation(), onDone: () { OpenFile.open('$path/loremipsum.pdf'); }, deleteOnCancel: true, ); core = await Flowder.download( "https://assets.website-files.com/603d0d2db8ec32ba7d44fffe/603d0e327eb2748c8ab1053f_loremipsum.pdf", options, );},我应用 OpenFile package 包在文件实现下载过程时关上它。我还应用了 percent_indicator package 包来显示停顿。 ...

November 2, 2021 · 1 min · jiezi

关于flutter:Flutter-UI自动化测试技术方案选型与探索

作者:小匠 Flutter页面无奈间接应用Native测试工具定位元素,给自动化测试带来很多不便。尽管Google官网推出了Flutter driver 和 Integration test,然而在理论应用中存在以下问题: 不适用于混合栈APP,尽管appium中有相干的driver,然而无奈切换环境;元素定位能力绝对单薄;依赖于VMService,须要构建Profile或Debug包。基于以上因素,咱们并没有间接应用Google官网推出的工具,而是抉择基于Native测试工具去扩大Flutter页面的测试能力。本文对Flutter driver 和Integration test的原理和实现进行了剖析,同时简略介绍闲鱼在UI自动化测试的尝试计划。 Flutter driver最早接触flutter自动化测试时,先尝试应用appium框架去驱动APP,当咱们应用inspect性能去dump页面元素时发现很多元素会被合并成一个区域块,而后点击的时候只能通过xpath定位,想定位到某些具体的元素会比拟艰难,并且xpath其实是容易扭转的,代码可维护性能力差。 因为上述起因,咱们开始调研Flutter官网提供的测试工具——flutter driver。一开始应用该框架的时候发现它只能实用于纯Flutter利用,对于混合栈利用并不适应,然而它底层提供的元素定位能力或者对咱们有用,于是咱们对它的源码进行了分析,该框架的原理图1如下所示。 图1 flutter driver原理图 整个框架的流程交互比较简单,测试脚本在运行时,首先利用FlutterDriver.connect()来连贯VMService获取相干的isolate,之后通过websocket来传输操作过程以及数据获取。其中测试脚本侧的所有操作都是被序列化为json字符串通过websocket传递给ioslate来转换为命令在APP侧执行,例如咱们想要获取某个组件的文本内容,其最终生成的json构造体如下: {"jsonrpc":"2.0","id":5,"method":"ext.flutter.driver","params":{"finderType":"ByValueKey","keyValueString":"counter","keyValueType":"String","command":"get_text","isolateId":"isolates/4374098363448227" }}理解上述原理后,就能够通过结构协定格局,在任何语言、测试框架下都可能去驱动flutter测试,所以咱们对这个协定进行了封装,应用Python进行驱动,这样能够在应用uiautomator2和facebook-wda的根底上来测试flutter页面,以满足flutter混合栈利用的测试需要。最终的实现代码demo如下。 from flutter_driver.finder import FlutterFinderfrom flutter_driver.flutter_driver import FlutterDriverimport uiautomator2 as u2if __name__ == "__main__": d = u2.connect() driver = FlutterDriver(d)if pageFlutter is True: # 如果是flutter,则应用flutter driver进行驱动 driver.connect("com.it592.flutter_app") finder = FlutterFinder.by_value_key("input") driver.tap(finder) time.sleep(1) print(driver.getText(FlutterFinder.by_value_key("counter")))else: d(text="increase").click()咱们尝试应用该套框架,发现其实flutter driver底层提供的能力绝对比拟单薄,并不能齐全满足咱们的需要,次要问题如下: 不能批量操作元素,一旦finder定位到的元素超过1个时,就会抛出异样;很多时候开发同学不写key,元素定位也没那么不便;因为flutter没有inspect工具dump元素,所以只能利用联合源码去写脚本,代码保护老本比拟高;官网曾经放弃保护该我的项目,所以后续预计也不会有新性能反对。integration_test后面提到,flutter官网放弃保护Flutter driver,并推出新的测试框架integration_test,那么这个框架会不会对混合栈利用予以反对呢,事实上试用了之后发现事件并没有咱们想的那么美好。在官网文档里有这么一句话“该软件包可在设施和模拟器上对Flutter代码进行自驱动测试”。 integration_test底层的元素操作和定位还是基于flutter_test去驱动的,其劣势次要如下: 测试脚本能够应用各种Flutter的API;打包ipa、apk后就能在 Firebase Test Lab等设施群上运行测试,不须要额定驱动;integration_test的每个页面之间测试无关联,能够实现单个页面级别的测试。然而因为底层元素定位和Flutter driver的是统一的,所以Flutter driver存在的问题仍旧存在,同时还存在其余局限问题: 测试脚本打包到APP中,每次批改脚本都须要从新打包;对端到端测试不够敌对,须要额定函数来期待数据加载结束;不适宜全链路级别的页面测试;可扩展性弱。基于以上问题,不满足咱们的应用需要,所以咱们只是做了简略预研,并没有深刻理解和利用。 闲鱼UI自动化测试计划学习Flutter官网推出的相干测试框架之后,咱们开始思考闲鱼UI自动化到底要怎么走?是站在官网的肩膀下来造轮子还是复用现有的原生自动化测试能力去扩大Flutter测试能力。在综合思考投入老本以及测试脚本的保护难度后,咱们抉择应用图像处理技术来裁减原生自动化框架对Flutter页面的测试能力反对,整个测试计划架构如图2所示。 图2 闲鱼UI自动化测试计划架构 Flutter的元素不是齐全不能被uiautomator2和facebook-wda辨认,所以编写测试脚本时只须要解决不能被辨认的元素即可。对于有name、label以及xpath不易扭转的元素定位,咱们优先应用原生定位能力进行定位操作,其余元素则间接应用图像处理技术进行定位操作。 ...

November 2, 2021 · 1 min · jiezi

关于flutter:Flutter-到底能不能做-APP-GetX-能实战么我上架了一款APP-Helber

前言群里有不少新退出的敌人,大家会有一个纳闷,就是 Flutter 做 app 到底靠谱么。 还有这个 GetX 实战中的体现如何,是否有大坑。 我这边上架了一款产品 helber,大家能够直观的体验下。 官网https://helberapp.com/苹果店https://apps.apple.com/app/id...谷歌店https://play.google.com/store... 利用的业务是按地理位置社交互助。 尽管是寰球可用,然而主打的还是北美,服务器也是西雅图。 欢送加微信技术内测探讨 ducafecat,备注 helber 用到的组件# The following adds the Cupertino Icons font to your application.# Use with the CupertinoIcons class for iOS style icons.cupertino_icons: ^1.0.2get: ^4.3.6dio: ^4.0.0# 权限permission_handler: ^8.1.2# app信息package_info: ^2.0.2# 本地存储shared_preferences: ^2.0.8# 刷新加载pull_to_refresh: ^2.0.0# toast 提醒flutter_easyloading: ^3.0.3# 底部弹出框modal_bottom_sheet: ^2.0.0# 输入框pinput: ^1.2.0# 适配屏幕flutter_screenutil: ^5.0.0+2# 网络图片cached_network_image: ^3.1.0# 媒体抉择wechat_assets_picker: ^6.0.4wechat_camera_picker: ^2.4.1# 滑块carousel_slider: ^4.0.0# svgflutter_svg: ^0.22.0# 瀑布流waterfall_flow: ^3.0.1# 加密crypto: ^3.0.1# OSSaliyun_oss_flutter: ^1.0.5# 视频图片压缩video_compress: ^3.1.0flutter_image_compress: ^1.1.0# 图片预览photo_view: ^0.12.0# 视频播放chewie: ^1.2.2video_player: ^2.2.5# 抉择# flutter_cupertino_datetime_picker: ^2.0.1flutter_picker: ^2.0.2# 工夫转换intl: ^0.17.0# 定位geolocator: ^7.6.2# 地图google_maps_flutter: ^2.0.11google_maps_cluster_manager: ^3.0.0+1# 缓存flutter_cache_manager: ^3.1.2# webkitwebview_flutter: ^2.0.12# 关上urlurl_launcher: ^6.0.12# 降级r_upgrade: ^0.3.5version: ^2.0.0# app 关上 uriuni_links: ^0.5.1# IMtencent_im_sdk_plugin: ^3.5.0# 腾讯推送tpns_flutter_plugin: git: url: https://gitee.com/ducafecat/TPNS-Flutter-Plugin# google signgoogle_sign_in: ^5.1.1# apple signsign_in_with_apple: ^3.2.0# facebook signflutter_facebook_auth: ^3.5.2# sentrysentry_flutter: ^6.0.1# 头部背景# draggable_home: ^1.0.2# 第三方登录按钮auth_buttons: ^1.0.1+4# 倒计时timer_count_down: ^2.2.0我的项目规模页数: 40~50 ...

October 26, 2021 · 1 min · jiezi

关于flutter:Flutter-模式对话框

原文https://betterprogramming.pub...代码https://github.com/macro6461/... 参考https://stackoverflow.com/que...https://stackoverflow.com/que...https://stackoverflow.com/use...注释如果你是从我以前的帖子来的,你看到我启动了我的待办事项应用程序,解决了我状态更新时不能用 showModalBottomSheet 办法更新 NewToDo 的问题。 在 Stack Overflow 上问了一个问题之后,我终于能够把我的 NewToDo 小部件放到 showModalBottomSheet 中了。这样,NewToDo 小部件只有在我单击 FloatingActionButton 时才可见,而不是必须始终可见。 然而,在实现这个指标后不久,我留神到我的应用程序中还有一个问题。 当我抉择要编辑的 ToDo 我的项目时,我心愿可能重用我的 NewToDo。我认为这是有意义的,因为它是同样的两个输出,能够用来扭转雷同的两个状态值,title 和 content。 问题是什么? 除了在我的 FloatingActionButton 小部件(绿色圆圈)的 onPressed 办法之外,我无奈在任何中央执行 showModalBottomSheet (绿色箭头)。 我须要可能触发 onPressed 办法,每当我点击编辑题目 ElevatedButton 小部件(红色圆圈标记) ,每个 ToDo 我的项目。 我思考了如何找到一种办法来模仿 onPressed 事件,以便执行 showmodbottomsheet 回调。 因为无奈模仿 onPressed 事件(and frustrated) ,我带着 Stack Overflow 去看看是否有其他人对如何实现我所寻找的指标有任何想法。 过了一会儿,我失去了答案。我松了一口气... ... 也谦卑起来。 如此简略... 如此纯净 我驳回了 eimmer’s 的倡议,没有把我的 showModalBottomSheet 放在 onPressed 办法中,而是把它分解成了它本人的函数 renderShowModal。参见下文: ...

October 24, 2021 · 1 min · jiezi

关于flutter:flutter登录注册编写

登录页-页面剖析 步骤: ①将无状态组件改成有状态组件-右键 重构 ②增加可点击的图标-iconButton ③增加状态-showPassword ④依据状态展现不同内容 ⑤给图标增加点击事件 ⑥测试 问题及解决方案: 1、去注册色彩问题 增加style 2、高低间距问题?增加Padding 3、边距/异形屏幕问题 应用SafeArea 4、垂直高度有余问题应用listView代替Column 5、登录按钮宽度和色彩问题? 宽度:SizeBox或者父级固定宽度 色彩:手动设置 注册页-页面剖析 步骤: ①增加文件/pages/register.dart ②将login.dart文件复制到register.dart ③批改类名 ④批改title ⑤在路由增加register ⑥测试 ⑦优化登录注册跳转,应用Navigator.pushReplacementNamed登录页面 import 'package:flutter/material.dart';import '../routes.dart';class LoginPage extends StatefulWidget { const LoginPage({ Key key }) : super(key: key); @override _LoginPageState createState() => _LoginPageState();}class _LoginPageState extends State<LoginPage> { bool showPassword = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('登录'),), body: SafeArea( minimum: EdgeInsets.all(30), child: ListView( children: [ TextField( decoration: InputDecoration( labelText: '用户名', hintText: '请输出用户名' ), ), Padding(padding: EdgeInsets.all(10)), TextField( obscureText: !showPassword, decoration: InputDecoration( labelText: '明码', hintText: '请输出明码', suffixIcon: IconButton( onPressed: (){ setState(() { showPassword = !showPassword; }); }, icon: Icon(showPassword ? Icons.visibility_off : Icons.visibility), ) ), ), Padding(padding: EdgeInsets.all(10)), // ignore: deprecated_member_use RaisedButton( color: Colors.green, onPressed: (){ }, child: Text('登录', style: TextStyle(color: Colors.white),), ), Padding(padding: EdgeInsets.all(10)), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('还没有账号,'), // ignore: deprecated_member_use FlatButton( onPressed: (){ Navigator.pushReplacementNamed(context, Routes.register); }, child: Text('去注册', style: TextStyle(color: Colors.green),) ) ], ) ], ), ), ); }}注册页面 ...

October 24, 2021 · 2 min · jiezi

关于flutter:flutter登录注册编写

登录页-页面剖析 步骤: ①将无状态组件改成有状态组件-右键 重构 ②增加可点击的图标-iconButton ③增加状态-showPassword ④依据状态展现不同内容 ⑤给图标增加点击事件 ⑥测试 问题及解决方案: 1、去注册色彩问题 增加style 2、高低间距问题?增加Padding 3、边距/异形屏幕问题 应用SafeArea 4、垂直高度有余问题应用listView代替Column 5、登录按钮宽度和色彩问题? 宽度:SizeBox或者父级固定宽度 色彩:手动设置 注册页-页面剖析 步骤: ①增加文件/pages/register.dart ②将login.dart文件复制到register.dart ③批改类名 ④批改title ⑤在路由增加register ⑥测试 ⑦优化登录注册跳转,应用Navigator.pushReplacementNamed登录页面 import 'package:flutter/material.dart';import '../routes.dart';class LoginPage extends StatefulWidget { const LoginPage({ Key key }) : super(key: key); @override _LoginPageState createState() => _LoginPageState();}class _LoginPageState extends State<LoginPage> { bool showPassword = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('登录'),), body: SafeArea( minimum: EdgeInsets.all(30), child: ListView( children: [ TextField( decoration: InputDecoration( labelText: '用户名', hintText: '请输出用户名' ), ), Padding(padding: EdgeInsets.all(10)), TextField( obscureText: !showPassword, decoration: InputDecoration( labelText: '明码', hintText: '请输出明码', suffixIcon: IconButton( onPressed: (){ setState(() { showPassword = !showPassword; }); }, icon: Icon(showPassword ? Icons.visibility_off : Icons.visibility), ) ), ), Padding(padding: EdgeInsets.all(10)), // ignore: deprecated_member_use RaisedButton( color: Colors.green, onPressed: (){ }, child: Text('登录', style: TextStyle(color: Colors.white),), ), Padding(padding: EdgeInsets.all(10)), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('还没有账号,'), // ignore: deprecated_member_use FlatButton( onPressed: (){ Navigator.pushReplacementNamed(context, Routes.register); }, child: Text('去注册', style: TextStyle(color: Colors.green),) ) ], ) ], ), ), ); }}注册页面 ...

October 24, 2021 · 2 min · jiezi

关于flutter:flutter-fluro-优化路由配置

问题: 谬误页面如何解决?带参数的页面如何解决? 步骤: 1、谬误页面解决 ①在/page目录增加not_found.dart ②实现NotFoundPage ③在router.dart增加_notFoundHandler ④在router.dart的configureRoutes中增加router.notFoundHandler=_notFoundHandler ⑤批改PageContent测试 2、带参数的页面解决 ①在/page目录增加room_detail/index.dart ②实现RoomDetailPage ③在router.dart增加_RoomDetailHandler ④在router.dart的configureRoutes中增加router.RoomDetailHandler=_RoomDetailHandler ⑤批改PageContent测试 not_found.dart import 'package:flutter/material.dart';class NotFoundPage extends StatelessWidget { const NotFoundPage({ Key key }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('404'),), body: Center(child: Text('您拜访的页面不存在')), ); }}room_detail/index.dart import 'package:flutter/material.dart';class RoomDetailPage extends StatelessWidget { final String roomId; const RoomDetailPage({Key key, this.roomId}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('roomId: $roomId'),), ); }}router.dart ...

October 24, 2021 · 1 min · jiezi

关于flutter:flutter-fluro-优化路由配置

问题: 谬误页面如何解决?带参数的页面如何解决? 步骤: 1、谬误页面解决 ①在/page目录增加not_found.dart ②实现NotFoundPage ③在router.dart增加_notFoundHandler ④在router.dart的configureRoutes中增加router.notFoundHandler=_notFoundHandler ⑤批改PageContent测试 2、带参数的页面解决 ①在/page目录增加room_detail/index.dart ②实现RoomDetailPage ③在router.dart增加_RoomDetailHandler ④在router.dart的configureRoutes中增加router.RoomDetailHandler=_RoomDetailHandler ⑤批改PageContent测试 not_found.dart import 'package:flutter/material.dart';class NotFoundPage extends StatelessWidget { const NotFoundPage({ Key key }) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('404'),), body: Center(child: Text('您拜访的页面不存在')), ); }}room_detail/index.dart import 'package:flutter/material.dart';class RoomDetailPage extends StatelessWidget { final String roomId; const RoomDetailPage({Key key, this.roomId}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('roomId: $roomId'),), ); }}router.dart ...

October 24, 2021 · 1 min · jiezi

关于flutter:flutter配置fluro

1、编写路由配置文件 ①创立routes.dart文件 并编写Routes类的根本构造 ②定义路由名称 ③定义路由处理函数④编写函数configureRoutes关联路由名称和处理函数 2、在Application中配置路由 ①定义router ②通过调用configureRoutes配置router ③在MaterialApp中应用router routes.dart import 'package:fluro/fluro.dart';import 'package:flutter/material.dart';import './pages/home/index.dart';import './pages/login.dart';class Routes { //1、定义路由名称 static String home = '/'; static String login = '/login'; //2、定义路由处理函数 static Handler _homeHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return HomePage(); }); static Handler _loginHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return LoginPage(); }); //3、编写函数configureRoutes关联路由名称和处理函数 static void configureRoutes(FluroRouter router) { router.define(home, handler: _homeHandler); router.define(login, handler: _loginHandler); }}application.dart ...

October 24, 2021 · 1 min · jiezi

关于flutter:flutter配置fluro

1、编写路由配置文件 ①创立routes.dart文件 并编写Routes类的根本构造 ②定义路由名称 ③定义路由处理函数④编写函数configureRoutes关联路由名称和处理函数 2、在Application中配置路由 ①定义router ②通过调用configureRoutes配置router ③在MaterialApp中应用router routes.dart import 'package:fluro/fluro.dart';import 'package:flutter/material.dart';import './pages/home/index.dart';import './pages/login.dart';class Routes { //1、定义路由名称 static String home = '/'; static String login = '/login'; //2、定义路由处理函数 static Handler _homeHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return HomePage(); }); static Handler _loginHandler = Handler(handlerFunc: (BuildContext context, Map<String, dynamic> params) { return LoginPage(); }); //3、编写函数configureRoutes关联路由名称和处理函数 static void configureRoutes(FluroRouter router) { router.define(home, handler: _homeHandler); router.define(login, handler: _loginHandler); }}application.dart ...

October 24, 2021 · 1 min · jiezi

关于flutter:Flutter-GetX-整个活2021仿开眼视频-dio封装

简介flutter 2.0降级空平安后,就始终安奈不住情绪。想整活。正好就业了。那就整一下子。 app安装包体验百度云 提取码:2mpq 蓝奏云 提取码:fpqc 我的项目地址github地址 预览 dio封装这里应用 艾维码 大佬的dio封装计划,分多个拦截器,解决dio的状态。白嫖现成文件能够应用本我的项目中的request文件夹,我会马上出一篇奶妈级dio封装帖子。(还是《艾维码》大佬的封装计划,做解说) 视频播放器视频播放还是应用稳固成熟的fijkplayer + 自定义批改的皮肤,满足日常,稳得一批。手势滑动音量亮度等都有 getX yydsgetx的呈现,使得全局共享数据变得及其简略。啥也不说了,yyds好吧

October 20, 2021 · 1 min · jiezi

关于flutter:Flutter-Dio-亲妈级别封装教程

前不久看到 艾维码 大佬的dio封装,通过摸索,改吧改吧,应用的不错。对于之前 艾维码 大佬文章中一些曾经生效的做了修改为什么肯定要封装一手?token拦挡,谬误拦挡,对立错误处理,对立缓存,信息封装(谬误,正确) Cookie???滚犊子不论cookie,再见 全局初始化,传入参数dio初始化,传入baseUrl, connectTimeout, receiveTimeout,options,header 拦截器等。dio初始化的时候容许咱们传入的一些配置 dio初始化的配置这里说下,之前 艾维码 大佬的帖子中的options,最新版的dio曾经应用requestOptions, 之前的merge,当初应用copyWith。详情向下看 如果要白嫖残缺的计划能够参考应用这套计划开发的 flutter + getx 仿开眼视频app,有star的大佬能够赏点star。 我的项目地址 github地址 apk下载 panbaidu 提取码:3ev2 初始化这里说下拦截器,能够在初始化的时候传入,也能够手写传入,例如我这里定义了四个拦截器,第一个用于全局request时候给申请投加上context-type:json。第二个是全局错误处理拦截器,上面的内容会介绍拦截器局部。cache拦截器,全局解决接口缓存数据,retry重试拦截器(我临时没怎么用) class Http { static final Http _instance = Http._internal(); // 单例模式应用Http类, factory Http() => _instance; static late final Dio dio; CancelToken _cancelToken = new CancelToken(); Http._internal() { // BaseOptions、Options、RequestOptions 都能够配置参数,优先级别顺次递增,且能够依据优先级别笼罩参数 BaseOptions options = new BaseOptions(); dio = Dio(options); // 增加request拦截器 dio.interceptors.add(RequestInterceptor()); // 增加error拦截器 dio.interceptors.add(ErrorInterceptor()); // // 增加cache拦截器 dio.interceptors.add(NetCacheInterceptor()); // // 增加retry拦截器 dio.interceptors.add( RetryOnConnectionChangeInterceptor( requestRetrier: DioConnectivityRequestRetrier( dio: dio, connectivity: Connectivity(), ), ), ); // 在调试模式下须要抓包调试,所以咱们应用代理,并禁用HTTPS证书校验 // if (PROXY_ENABLE) { // (dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = // (client) { // client.findProxy = (uri) { // return "PROXY $PROXY_IP:$PROXY_PORT"; // }; // //代理工具会提供一个抓包的自签名证书,会通不过证书校验,所以咱们禁用证书校验 // client.badCertificateCallback = // (X509Certificate cert, String host, int port) => true; // }; // } } ///初始化公共属性 /// /// [baseUrl] 地址前缀 /// [connectTimeout] 连贯超时赶时间 /// [receiveTimeout] 接管超时赶时间 /// [interceptors] 根底拦截器 void init({ String? baseUrl, int connectTimeout = 1500, int receiveTimeout = 1500, Map<String, String>? headers, List<Interceptor>? interceptors, }) { dio.options = dio.options.copyWith( baseUrl: baseUrl, connectTimeout: connectTimeout, receiveTimeout: receiveTimeout, headers: headers ?? const {}, ); // 在初始化http类的时候,能够传入拦截器 if (interceptors != null && interceptors.isNotEmpty) { dio.interceptors..addAll(interceptors); } } // 敞开dio void cancelRequests({required CancelToken token}) { _cancelToken.cancel("cancelled"); } // 增加认证 // 读取本地配置 Map<String, dynamic>? getAuthorizationHeader() { Map<String, dynamic>? headers; // 从getx或者sputils中获取 // String accessToken = Global.accessToken; String accessToken = ""; if (accessToken != null) { headers = { 'Authorization': 'Bearer $accessToken', }; } return headers; } Future get( String path, { Map<String, dynamic>? params, Options? options, CancelToken? cancelToken, bool refresh = false, bool noCache = !CACHE_ENABLE, String? cacheKey, bool cacheDisk = false, }) async { Options requestOptions = options ?? Options(); requestOptions = requestOptions.copyWith( extra: { "refresh": refresh, "noCache": noCache, "cacheKey": cacheKey, "cacheDisk": cacheDisk, }, ); Map<String, dynamic>? _authorization = getAuthorizationHeader(); if (_authorization != null) { requestOptions = requestOptions.copyWith(headers: _authorization); } Response response; response = await dio.get( path, queryParameters: params, options: requestOptions, cancelToken: cancelToken ?? _cancelToken, ); return response.data; } Future post( String path, { Map<String, dynamic>? params, data, Options? options, CancelToken? cancelToken, }) async { Options requestOptions = options ?? Options(); Map<String, dynamic>? _authorization = getAuthorizationHeader(); if (_authorization != null) { requestOptions = requestOptions.copyWith(headers: _authorization); } var response = await dio.post( path, data: data, queryParameters: params, options: requestOptions, cancelToken: cancelToken ?? _cancelToken, ); return response.data; } Future put( String path, { data, Map<String, dynamic>? params, Options? options, CancelToken? cancelToken, }) async { Options requestOptions = options ?? Options(); Map<String, dynamic>? _authorization = getAuthorizationHeader(); if (_authorization != null) { requestOptions = requestOptions.copyWith(headers: _authorization); } var response = await dio.put( path, data: data, queryParameters: params, options: requestOptions, cancelToken: cancelToken ?? _cancelToken, ); return response.data; } Future patch( String path, { data, Map<String, dynamic>? params, Options? options, CancelToken? cancelToken, }) async { Options requestOptions = options ?? Options(); Map<String, dynamic>? _authorization = getAuthorizationHeader(); if (_authorization != null) { requestOptions = requestOptions.copyWith(headers: _authorization); } var response = await dio.patch( path, data: data, queryParameters: params, options: requestOptions, cancelToken: cancelToken ?? _cancelToken, ); return response.data; } Future delete( String path, { data, Map<String, dynamic>? params, Options? options, CancelToken? cancelToken, }) async { Options requestOptions = options ?? Options(); Map<String, dynamic>? _authorization = getAuthorizationHeader(); if (_authorization != null) { requestOptions = requestOptions.copyWith(headers: _authorization); } var response = await dio.delete( path, data: data, queryParameters: params, options: requestOptions, cancelToken: cancelToken ?? _cancelToken, ); return response.data; } }dio拦截器上面咱们来看下拦截器,上面是一个解决解决拦截器案例 ...

October 19, 2021 · 8 min · jiezi