flutter 入坑记

说实话我平时很少去了解一下技术的动向,这也是我对前端了解得少之又少的原因了把。

不过入坑flutter的原因是,我提出代码重构的需求(本着多学点的意图),然后学长就推荐了flutter,让我去了解一下。

不过,起先我确实没怎么在意。仅仅去随便 Google 了一下,了解到flutter兼顾跨平台与原生的性能很优秀。

不过,后面才进一步的了解到,flutterGoogle新的操作系统Fuchsia的 UI。
我比较好奇FuchsiaWebview在 flutter 表现如何

因为,flutter+Webview目前来说真的是比较坑的。

了解更多

环境搭建

不用我讲,教程一大堆。总的步骤无非是:

  • 安装git
  • 安装flutter SDK
  • 安装Android studio
  • 安装给编辑器安装flutter插件
  • 运行flutter doctor检测

上述步骤做好之后就可以愉快的开启flutter之旅了。

上手 Dart

flutter只是一个框架,使用的语言是dart,之所以为何用dart网络上面有很多的讨论,这个显然不是我这种菜鸡需要关心的问题,不过知道了又如何?。

不过,话说回来,上手Dart确实很快,看过一边Language Tour后基本上就可以上手写flutter了,
当然不看也可以的,看看flutter书写的格式,基本上可以有个初步了解,这样再去看或许效果更好。

不过,需要注意的是,Dart中,每一个东西都是一个Object,没有初始化就是null值,这个和Golang大相径庭,Go中,创建了就可以用了。
此外,还应该了解到,Dart中的传值,只是一个引用,你声明的变量,基本上都是对某一个对象的引用。但是有些对象的属性是immutable,比如num,
这个时候再去赋值就会自动clone一个出来。

除此之外,Dart还是一个强类型的语言,这点和javascript不同。我个人当然是更喜欢这种强类型的语言,无它,只是因为是C语言出身。

然后就是,Dart的异步处理功能了。这点,最初接触的时候感觉很难理解,毕竟经常接触的语言Go都是线程分明。

而,Dart显然借鉴了其它语言的优点,在处理异步的时候很是nice的。

当然更多东西是三语两语是说不清的,此外Dart也在变化,有些语法糖可能也在变,为此还是多去看看文档比较好。

不过,我觉得学习一门语言无非要注意一下几点:

  • 数据类型
  • 常用的运算符
  • 基础的语法
  • 标准库

了解以上内容后,基本上就对语言有了一个整体的认识了。当然细节的部分可能需要绝大的时间来掌握和区分。这也是为啥精通一门语言是很耗时的一件事情。

上手 Flutter

关于Flutter我最喜欢的就是它的json类似的语法数(Widget Tree)。

我最早见到类似的东西还是在Qt上面的xml见到的。不过,当时实在是无知,不懂得为会有这样的奇葩写法。

让我爱上这种写法还是,尝试用GoGUI程序接触到的walk这个框架。当时就是类似json的这种写法,让我仿佛发现了新天地,兴奋了好久。不过,最好发现Go还是不适合写GUI程序,于是果断放弃。

这次的Flutter从语法上面支持这种写法,加上Hot load,这简直无敌了。修改代码即可看到结果,比起修改一下跑一次gradle那不知道爽了多少倍啊。

不过,过度的使用这种写法带来的问题就是,整个屏幕密密麻麻的 {}`[]`() 有时候很难区分哪里属于哪里。有时候改代码的时候,不小心多删了一个括号,然后就陷入了寻找括号配对的尴尬过程。

Flutter优秀的地方在于它的Widget树,几乎任何一个组件都可以添加到widget树中,我们只需用写好这个树,然后flutter会根据这个来构建我们的程序界面,已经相应程序的操作。

不过正式因为这个原因,非flutter原生组件Webview如何嵌入到widget树中,就是一个问题了。当然官方有给出了webview_flutter插件来实现将webview
插入带组件树的插件,但是由于flutter组件都是flutter管理的,因此非flutterwidget是不能正常收到点击等事件的,也就是无法进行正常的交互操作。

目前这块地方还是有很大的坑,比较好的一个解决方案就是使用flutter_webview_plugin插件,这个不同于将webview强行嵌入到widget树中,
而是实现一个应用内置的浏览器页面,可以减少因为弹出浏览器窗口而降低用户的体验效果。

一些小坑

SplashScreen 黑屏问题

这个问题一直困扰我很久,我发现别人的代码和我的配置一样,但是别人的就是不会出现短暂的黑屏。

这个问题在网络上面找了很多教程,不过大部分的解决方案是在AndroidManifest.xml添加如下内容

<meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />

然而并没有上面卵用,不过最后还是在 StackOverflow 上面看到一个答案给出一个官方链接,
划重点,是官方链接,解决方案是

<meta-data
                android:name="io.flutter.embedding.android.SplashScreenDrawable"
                android:resource="@drawable/launch_background"
                                                   />

有没有很气人啊,上面的方案显然是flutter低阶版本的方案,后面版本的flutter都是默认第一项了。

这里的教训就是,一定要看官方的文档,尽量少去看那些所谓的博客,因为其解决方案可能已经失效了。

Flutter 的 Webview 坑

Flutter 的官方插件,flutter_plugin 不能很好支持键普事件,经常崩溃,不建议使用

Json 序列化

flutter不支持反射

官方给出的说法是,反射会导致编译的代码量变多,还会影响到WidgetTree。

但是,flutterApp 中经常会需要处理很多json数据,如何优雅处理json是一个难题。

虽然官方有给出方案,使用json_serilizable,不过这需要我们手动给每一个json写一个专用的类,如果遇到json的嵌套,那就需要写更多了类了。

实属有些麻烦,目前使用的是json_model插件,这个插件是解析jsons目录下面的json文件,来为每一个文件自动生产一些代码,

不过用起来还是有些不舒服就是了,此外这个插件作者很久没有更新了。许多的功能确实不完全,不过应付小一点的 App 应该是足够了。

使用上的一些小问题

值得一提的就是,使用Dio中遇到的问题。总得来说Dio是一个非常不错的框架,但是有些地方确实让我有点难受。

比如说,Dio请求后如果遇到HttpStatusCode200的情况会抛出一个异常,虽说这样没有上面不好,但是有时候可能需要根据返回的状态码的不同来进行一些不同的操作,如果这样的话,这个逻辑就得写在On DioError catch(e)里面了,感觉有那么的一点点不方便。不过,这也可能和我刚刚解决类似Dart这样的语言有关系吧,毕竟之前都是接触golang的错误处理方式,这样一下子还真有点不适应。

再者就是,Dio会自作聪明的将返回的数据进行解析,比如说如果是json数据,data就自动解析成一个Map<String,dynamic>类型,这时候面得返回数据可能不是一直都是json的时候需要额外判断一下类型。

总结

总体上flutter给人的感觉是非常nice的,尽管目前来说还有很多的坑需要填,不过flutter在国内已经有商用的 App 了咸鱼

此外,flutter的插件还是蛮多的,我相信flutter一直在向好的方向发展,也期望这些坑能经量都填上。

最好,如果是个人开发的话,flutter开发时非常快速的,尤其是hot reload简直就是神奇。

由于本人接触不久,对flutter理解还是很不到位,可能内容会有一些错误,望见谅。

END

Last modification:March 17th, 2020 at 10:36 am
要饭啦~