我的第一个Flutter 应用Demo Aireport

image

在大略看完了Flutter的官方文档后, 我开始尝试做一个完整的应用Demo. 抱着初次开发不要给自己挖坑的前提, 我选择了一个简单而实用的空气质量项目: Aireport. 这是我之前自己开发的一个iOS原生App, 因为是给自己用, 因此项目很简单, 几百行代码. 同时做一款Flutter版的Aireport也能够探寻两者具体的差异点.


UI

首先说一下Flutter应用的开发流程.

第一步自然是新建工程.根据我的《闭坑指南》,编辑器还是强烈建议使用Google自家的Android Studio, 无论是插件支持程度还是速度上都要好上不少(和VS Code相比).

然后是引入第三方库.这里我使用了最基本的几个库, 包含有图标库、网络库、json转model以及本地存储.

cupertino_icons
http
json_annotation
shared_preferences

Flutter目前还没有提供一个非常好的json转model的方案, json_annotation是官方目前推荐的“最方便”的model库, 但还是需要通过脚本的方式生成json转model类. 这显然没有动态转换但效率高.

我在网络层和UI层之间做了一个简单的存储层, 用于缓存网络请求的数据.

接下来就是正式开始编写代码咯. 作为一个略懂前端的iOS开发者, Dart本身的语法上手速度还是很快的, 不过这个层层嵌套的结构实在是太恶心了, Android Studio自带的代码格式化似似乎也不太稳定.

其次是Flutter的布局. 大体的布局和前端布局框架很相像, 但它将功能“过分组件化”了, 原本DIV都有都Padding、Center、Align属性全部Widget化, 因此如果你的布局比较复杂, 很可能需要多个布局Widget嵌套来实现.

看到这样的代码我的内心是崩溃的

看到这样的代码我的内心是崩溃的💔

如果你是原生开发者, 你会很自然的认为TableView(ListView)、CollectionView(GridView)是一个UI控件,包含了对Cell的展示、控制、点击事件的处理. 而Flutter将这个控件拆分成了多个组件,ListView和GridView仅仅承担布局的工作, 点击事件等需要通过别的控件来实现.

可以这样理解, Flutter尽可能的将UI、布局、功能进行分解Widget化, 我还不确定这样做的目的是出于性能优化的考虑还是别的原因. 当然适当的组件化是好的, 能够使控件足够灵活, 也能对性能有适当提升. 但如此小颗粒度的分解目前看来也带来了一些使用上的问题, 包括上面提到的多层嵌套.

当你的代码写的差不多的时候, 就要开始调试代码. 调试Flutter的过程是愉悦的, 任何更改后按下保存快捷键你就能立刻看到修改后的样子(理想情况下).令人欣慰的是Android Studio还提供了足够强大的调试工具来帮助我们进行纠错, 在这点上VS Code能做的就很少了, 至少目前来说.

如果需要对UI进行调试, 可以尝试加入

import 'package:flutter/rendering.dart';
debugPaintSizeEnabled= true;
image

通过辅助线我们可以快速定位控件的布局


image

Android Studio还提供了inspector视图, 包含了Widget树状图以及了Widget的各种属性, 类似于浏览器的调试器. 不过目前的视图还比较混乱, 应该是把底层的所有Widget无差别展示出来, 对于感兴趣底层实现的同学可以研究一下.

项目开发完成, 接下来就是打包发布了. Flutter有两种运行方式, debug模式提供了热更新等功能方便我们快速开发, 但运行效率低下. 而release模式剔除了无用的功能并以AOT方式运行, 效率更高.

flutter build ios

构建release的iOS版本, 然后去Xcode中设置app的Icon、启动页、版本号、证书等等, 就如同一般的原生应用一样. 注意, 如果你的app中使用了非HTTPS协议还是需要在Plist中对安全规则进行修改, 地理位置、相机权限也是同理.

至此, 我的Flutter iOS项目已经开发完成了. App Store2天左右就通过了审核, 显然目前Apple对于Flutter的态度还是和善的, 但未来的政策还是未知.

在开发这个项目的过程中, 我遇到了几个问题, 也想跟大家分享一下.

首先是布局.


image

这个页面其实相当简单, 上面是一个搜索框, 下面是一个ListView. 但我始终无法通过简单的布局实现这个效果. 一开始我本能但使用Column来放置两个控件, 但报错, 提示的大意是不能在一个可以滚动的组件内部套另一个可以滚动的组件, 因为无法确定子组件的高度. Column的布局其实类似iOS中的ScrollerView, 他的内部填充高度是无限的, 和屏幕高度无关. 可以给ListView添加高度解决问题, 但我又无法计算当前ListView的具体高度(方法是有, 但我觉得太复杂了, 还要区分X这种特殊机型).

最后我使用了Stack, 将搜索框悬浮在ListView之上, 再给ListView套一个Container设定到上边距的距离, 最终实现了这个效果. 虽然最终的效果还可以, 但我觉得这样但布局明显还不够优雅, 阅读起来难度也很大. 如果有更好但解决办法请告诉我.

其次是尚有很多系统层级的功能无法实现. 比如StatusBar的颜色, 我希望的是首页是白色字体, 搜索页是黑色字体. 但目前似乎只能设置一种固定的颜色. 尝试使用SystemChrome强制设置StatusBar的颜色,但跳转到搜索页颜色又会变为黑色, 返回时不能自动变为白色. 尝试寻找类似于ViewWillAppear这样的事件无果, 暂时只能通过后一个页面的回调来触发修改颜色的代码.

Notification也是一个暂时无法实现的功能.目前官方已经提供了firebase_messaging插件用于收取推送消息, 但无法发送本地推送, 也就无法实现小圆点的功能.当然我们还是可以通过调用原生方法实现.

总结一下.

从UI层面, Flutter由于提供了一套脱离特定平台的自有渲染引擎, 几乎能够实现任何你想要达到的效果. 但在这之前你可能需要好好研究一下它的布局Widget, 然后暂时(可能永远)忍耐一下多层嵌套的代码风格. 当然适当将自己的页面组件化也是一个好的方法.

逻辑层面, 官方已经推出了数量可观的基础库, 处理基本的事务没有特别大的问题. 但我们还是希望有大量好用的第三方库出现, 丰富Flutter的开发生态.

下一篇会做一个iOS原生应用和Flutter的对比评测.

最后放上项目GitHub地址: https://github.com/jihongboo/Aireport_Flutter
现已上架AppStore: https://itunes.apple.com/cn/app/aireport-flutter/id1390259423?mt=8

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,409评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,016评论 4 62
  • “从此萧郎是路人。” 我是爱你的,很爱很爱。 我记得第一次听到你的名字,很震憾,听到过好听的名字不少,你却独独出众...
    沐尧阅读 654评论 0 3
  • 同事:你最近遇到不开心的事情了嘛?感觉你有点暴躁~ 我:啊~没有啊~何出此言 同事:因为今天大家在年会群里要你提供...
    一个陌生女生阅读 296评论 1 4
  • 意中五柳袅轻烟,空案微弹似抚弦。 管葛大才难得用,高山流水自涓涓。
    陆沉_3753阅读 402评论 1 1