如何用Flutter在兩周以內(nèi)上架一個小項目拂苹?For iOS or Android dev.

原文地址:
https://juejin.cn/post/6967645147207041054

前言

前些日子朋友咨詢可否爬網(wǎng)站數(shù)據(jù),并制作一Windows程序痰洒。作為開發(fā)iOS/Android/MacOS/WatchOS/...的我沒接觸過C++/C#瓢棒,用Java開發(fā)也不現(xiàn)實,重新認識Windows組件丘喻、網(wǎng)絡脯宿、資源管理還是比較耗時的,于是打算推薦其使用眾包平臺發(fā)布任務泉粉。轉(zhuǎn)念一想连霉,大Flutter豈不是最合適之選,「Write once, Run anywhere」嗡靡,可以避免平臺兼容難跺撼、學習成本高等眾多問題,最終在筆者挖坑填坑之旅中更加確定讨彼,Flutter會是移動端的未來歉井。

本文為筆者利用下班和周末時間邊學邊做項目的歷程,希望對于Flutter入門者有所幫助哈误。其中大多為開發(fā)建議哩至、推薦和思路躏嚎,并非代碼級的指引。閱讀本文大約需20分鐘憨募。
**

一紧索、準備工作

1、Flutter開發(fā)環(huán)境菜谣、開發(fā)工具珠漂、學習資料

工欲善其事,必先利其器尾膊。
開發(fā)Flutter如果想要同時打包iOS&Android媳危,必須要有一臺Mac電腦,沒有怎么辦冈敛?發(fā)揮你程序員的優(yōu)勢待笑,安裝MacOS虛擬機并在蘋果官網(wǎng)下載Xcode安裝包
建議使用Android Studio(AS)開發(fā)抓谴,下載Flutter和Dart插件即可峦耘,更好兼容安卓模擬器吸占。
筆者電腦安裝有Xcode和AS所刀,所以只需安裝Flutter SDK即可撰洗,安裝后使用萬能指令,flutter doctor滩届,發(fā)現(xiàn)問題集侯,解決問題。

flutter doctor

注:Android license status unknown的警告是因為我本地java版本過高帜消,不影響開發(fā)棠枉,可以忽略。
當然泡挺,也可以使用Visual Studio開發(fā)辈讶,開發(fā)Windows程序必選。并且編譯打包EXE文件時娄猫,必須在Windows10電腦環(huán)境運行荞估。
(所以筆者在項目收尾階段安裝Windows10虛擬機并安裝VS后才能打包,占用我電腦40G的存儲稚新。??????)

②推薦一些學習Flutter的學習資料網(wǎng)站:

字節(jié)跳動-幸福里FE團隊某大神制作,入門最佳選擇跪腹,保姆級資料褂删。

官網(wǎng)資料冲茸,最為可靠屯阀。版本新缅帘,資源全,手把手視頻教學及在線練習體驗难衰。

最全的中文控件庫钦无,使用與需求更貼切的良心官方控件,省時省心又省力盖袭。
吐槽一下用Android寫UI失暂,Android(ListView,RecycleView)輸于iOS(UITableView,UICollectionView)的原因,就是iOS基本不需要自定義適配器鳄虱。但Android使用XML寫UI弟塞,非常方便,強于Xib拙已。

相當于iOS之Cocoapods决记,Android之jcenter。常用第三方庫可在中文網(wǎng)資料中獲取倍踪,這里不一一列舉系宫。
強調(diào)一下,第三方庫的疊加依賴會導致兼容失敗建车,一般情況下扩借,使用any版本即可,pub管理工具會自動下載不造成沖突的版本。特殊情況需要下載離線庫進行配置癞志。某些工具庫在編譯時需要注釋掉往枷,例如hive_generator,自動生成model屬性轉(zhuǎn)換方法時需要添加凄杯,編譯時不注釋會報錯Dart Error: error: import of dart:mirrors is not supported in the current Dart runtime

值得推薦错洁,以成品介紹組件〗渫唬可惜的是可能是因為《閑魚》App性能問題屯碴,阿里內(nèi)部對Flutter熱情不再,2年前已暫停維護膊存。關(guān)于性能問題导而,目前的Flutter2.2已經(jīng)有不小的性能提升和生態(tài)支持完善。

含高仿抖音隔崎,斗魚今艺,豆瓣,開源中國爵卒⌒槎校基本包含市場App所有功能板塊。

2钓株、了解分析需求实牡,爬取需求數(shù)據(jù)陌僵,確定開發(fā)流程

①需求

  • 表格展示專業(yè)列表,可操作创坞、可分頁碗短。
  • 多維度多條件查詢
  • 方案列表,編輯题涨、切換方案
  • 按需導出Excel表格
  • 注冊偎谁,登錄,Token

②爬取網(wǎng)站數(shù)據(jù)

凡是爬取網(wǎng)站里面不讓爬取數(shù)據(jù)的行為都是不道德/違法的携栋。

實際上搭盾,各公司之間有很多數(shù)據(jù)都是相互爬。但這也沒有抵消筆者愧疚之心婉支。況且此網(wǎng)站要爬取的接口都是有經(jīng)過MD5加密后的動態(tài)Token的鸯隅,所以再次打算推薦其使用眾包平臺。

在JS調(diào)試窗口向挖,除標頭還有預覽頁面蝌以。驚喜的是,網(wǎng)站的數(shù)據(jù)按500條/頁展示在預覽中何之,也就是說跟畅,我們只需要拷貝50頁數(shù)據(jù)即可。??????
用命令行touch data{0..49}.json創(chuàng)建50個文件溶推,依次粘貼文本徊件。制作一個小工具,融合50個json文件得到1個20M的json文件蒜危,這樣我們就得到原始數(shù)據(jù)虱痕。
當然,后續(xù)對數(shù)據(jù)查找和性能的優(yōu)化過程中辐赞,按照本科部翘、專科响委、體育新思、藝術(shù)、提前類型分為5個json文件赘风,查找速度從原來的600ms提高到400ms以內(nèi)夹囚。

你問我為什么不直接粘貼在一個json文件里?有興趣的朋友可以試用任何編輯器打開20M的json文件邀窃。
~~
③開發(fā)流程

  • 創(chuàng)建新Flutter App崔兴,默認已勾選iOS、Android,選擇MacOS及Windows平臺敲茄,若不能勾選,flutter config --enable-macos-desktopflutter config --enable-windows-desktop山析,重新創(chuàng)建堰燎。所有的開發(fā)都可以在Mac上進行,最后打包的時候再無縫移植到Windows笋轨。
  • UI秆剪,數(shù)據(jù)庫,交互爵政,邏輯仅讽,工具等。
  • 平臺兼容钾挟,原生開發(fā)洁灵,F(xiàn)lutter與原生通信交互。
  • 完善應用信息掺出,規(guī)正權(quán)限徽千,提交審核。
  • 應用已上架Mac App Store汤锨,應用地址為《選校方案》双抽,Windows版稍后發(fā)布在云盤中。

二闲礼、功能模塊

遍歷《選校方案》的功能模塊牍汹,分析其中使用的Flutter知識,從iOS和Android開發(fā)者視角來解釋柬泽。

1慎菲、UI:萬物基于Widget通俗來講聂抢,StatefulWidget是可變的控件钧嘶,StatelessWidget是不可變的控件。單從創(chuàng)建UI來講琳疏,Android dev更有優(yōu)勢一些有决,因為XML也是嵌套模式。iOS dev接觸過SwiftUI或者Rx系列或者RAC更容易理解空盼,嵌套型UI是把iOS中所有約束书幕,屬性,控件揽趾,參數(shù)台汇,交互、動畫融合在一起,不以控件為主要對象苟呐,形成的響應式UI痒芝。從開發(fā)便利性來說,筆者感覺Hot Reload響應式編程是所有移動端的趨勢牵素。
①避免嵌套严衬,以封裝治理地獄式套娃

  • 不論是單人還是多人開發(fā),如果無休止的添加單個自定義Widget笆呆,一個復雜頁面動輒幾千行请琳。對于后期維護者來說,結(jié)構(gòu)調(diào)整困難赠幕,邏輯交互入口混雜難以分辨俄精,簡直難受至極。
  • 常用UI模塊進行封裝榕堰,減少代碼量竖慧,使結(jié)構(gòu)清晰。
  • 在這里推薦Bloc模式<可理解為MVP>局冰,簡單頁面還是以StatefulWidget為主测蘑,如有多個頁面共享同一數(shù)據(jù)的業(yè)務場景,就非常適合康二。
  • 整個UI布局封裝后在Bulid內(nèi)也只有25行代碼碳胳。
@override
  Widget build(BuildContext context) {
    passValue = ModalRoute.of(context).settings.arguments;
    return Scaffold(
      body: Column(
        children: [
          _getTopSearchView(context), //頂部搜索欄
          Container(
            height: 40,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              itemBuilder: (BuildContext context, int position) {
                return _getTitleColumn(position, Global.titles[position]);
              },
              itemCount: Global.titles.length,
              controller: firstRowController,
            ),
          ),//數(shù)據(jù)表頭
          Expanded(child: Container(child: _getCoreListView())),//數(shù)據(jù)核心區(qū)
          _getPageView()//分頁區(qū)
        ],
      ),
    );
  }
  • 以部分UI舉例,將寬度沫勿、邊框?qū)傩园ぴ肌⒕又袛?shù)據(jù)、背景顏色進行封裝产雹。代碼篇幅較長诫惭,以圖片替代展示。
image-2.png
image-3.png

②整體布局的思路


image-4.png
  • 標題搜索欄以外層Wrap嵌套蔓挖,流式布局可以使控件居中并設置行/列間距夕土,自動適配整體窗口寬度。Dropdown瘟判、TextFiled怨绣、Button在iOS、Android中也有類似控件拷获,唯一不同的是篮撑,獲取控件的動態(tài)值時,并不是直接以控件的屬性值來獲取匆瓜,而是通過TextEditingController監(jiān)聽赢笨、動態(tài)字符串變量等方式未蝌。
Wrap(
alignment: WrapAlignment.center,
spacing: 20,
runSpacing: 10,
children: []
)
  • 數(shù)據(jù)表頭設置為橫向ListView,添加ScrollController茧妒,與數(shù)據(jù)展示區(qū)的ScrollController相互監(jiān)聽萧吠,完成同步滾動功能。
//監(jiān)聽第一行變動
firstRowController.addListener(() {
  double offset = secondedRowController.offset;
  double offset1 = firstRowController.offset;
  if (offset1 != offset) {
    secondedRowController.jumpTo(offset1);
  }
});
//監(jiān)聽第二行變動
secondedRowController.addListener(() {
  double offset = secondedRowController.offset;
  double offset1 = firstRowController.offset;
  if (offset != offset1) {
    firstRowController.jumpTo(offset);
  }
});
  • 數(shù)據(jù)展示區(qū)的UI相當復雜嘶伟,既要保證橫豎向都能滾動怎憋,又要考慮滾動性能,還要展示{500條/頁}數(shù)據(jù)懶加載九昧。

筆者耗時整整兩天才搞定此功能,一開始使用官方控件DataTable毕匀,發(fā)現(xiàn)在自定義單元格展示不同UI時铸鹰,需大量代碼匹配其代理方法;滾動性能極差皂岔;不可懶加載蹋笼,遂代碼全部廢棄,重新布局躁垛。
受益于iOS構(gòu)建UI時的靈活性處理剖毯,筆者突發(fā)奇想,使用橫向SingleChildScrollView內(nèi)部嵌套豎向ListView教馆,ListView使用itemBuilder構(gòu)建逊谋。這樣一來,橫豎向滾動土铺,性能胶滋,懶加載全部擁有。
單條item最后的“添加/刪除”按鈕操作悲敷,刷新UI幾乎無卡頓究恤。

  • 分頁區(qū):若為固定長度,會導致Flutter UI的經(jīng)典(Overflow)屏幕溢出問題后德,黃黑斜條紋顯示區(qū)域為UI警告(駕考寶典中為立面標記部宿,一般在隧道口??),所以外層以SingleChildScrollView嵌套瓢湃,窗口較小時理张,不會出現(xiàn)此警告。

更換100條/頁或其他頁碼時箱季,使用實例變量來標記單頁條數(shù)涯穷,數(shù)組的getRange方法重新分割數(shù)據(jù),刷新ListView與頁碼數(shù)藏雏。

image-5.png

2拷况、數(shù)據(jù)庫

Hive作煌,pub上1.8KLike,GitHub上2.3kStar赚瘦,在Flutter中算是歡迎度比較高的粟誓。

  • 配合hive_generator使用,可存儲模型起意,使用方便鹰服。
  • 不必寫SQL語句,可直接按數(shù)組/Map形式存儲
  • CURD速度極快

項目中建表方式:

  • 創(chuàng)建方案列表庫揽咕,與專業(yè)數(shù)據(jù)庫相互關(guān)聯(lián)悲酷。在每個方案中包含專業(yè)列表。
  • 方案model中增加isCurrentPlan屬性亲善,切換現(xiàn)有方案時正反賦值设易。
  • 創(chuàng)建用戶屬性庫,存儲用戶手機號蛹头、密碼顿肺、昵稱、角色權(quán)限(普通角色只能看到1000條數(shù)據(jù))渣蜗、已登錄狀態(tài)

shared_preferences屠尊,類似于iOS之NSUserDefaults,Android之SharedPreferences耕拷,可用于本地小數(shù)據(jù)存儲讼昆。

3、第三方庫斑胜、全局文件及資源庫

  • 麻雀雖小五臟俱全控淡,項目小但功能全,添加第三方庫時止潘,使用flutter pub get/upgrade等命令掺炭,本App集成的第三方庫有:
image-6.png
  • 常用功能及第三方庫列表
  • pubspec.yaml是Flutter項目的核心配置文件,iOS dev需要能接受非可視化配置凭戴,這點Android dev習以為常涧狮,與build.gradle相似。包含本地圖片么夫,本地文件者冤,第三方庫,字體等档痪。
  • 創(chuàng)建Global類文件涉枫,存放常用常量/變量,便于程序調(diào)用腐螟。

4愿汰、與原生通信困后,原生適配。

  • 用Xcode/AS單獨打開各自平臺文件夾中的項目衬廷,應用名稱摇予、圖標、啟動圖等需原生適配吗跋,iOS在Info.plist文件中添加權(quán)限侧戴,Android在Manifest.xml中配置權(quán)限等。如果有Flutter實現(xiàn)不了的功能或者因平臺特殊要求跌宛,還是需要去做原生開發(fā)酗宋。關(guān)于Theme,偏向iOS/Android疆拘,都有相應的風格組件本缠,還可以統(tǒng)一設置全局Theme。只需要此時就需要一個Flutter交流群入问,互相幫助,隨時能夠解決平臺開發(fā)者在iOS/Android的原生適配開發(fā)問題稀颁,希望有號召力的大佬搞一個芬失。
  • 與JS原生交互的原理基本相同,無非是建立相同命名的通道匾灶,A發(fā)送方法名稱和參數(shù)棱烂,B通過回調(diào)接收。網(wǎng)上資料很多阶女,自行百度吧颊糜,沒必要在這里重復造輪子。

本App有導出Excel文件的需求(MacOS與iOS通信方式相同)秃踩,此時就需要做平臺兼容(Platform.isAndroid or Platform.isIOS etc.)衬鱼。對于Windows平臺來說,沒有強制規(guī)定向用戶請求權(quán)限憔杨,所以直接保存至任何普通文件地址鸟赫,觸發(fā)Flutter事件后調(diào)用原生SavePanel方法。對于MacOS來說消别,需要請求User Selected File-Read/Write抛蚤,而不是下面的Folder權(quán)限,并啟動原生文件保存窗口寻狂。這也是審核被拒的重要原因岁经。

image-7.png
image-8.png

5、macOS App Store上架歷程(由于App Store的嚴格審核機制蛇券,一定要把握住權(quán)限缀壤,連續(xù)5天幾個版本的拒審你懂的樊拓。Android dev可以略過)

  • Debug階段,開啟Incoming Connections(Server)是必需的诉位,因為Hot Reload基于此權(quán)限骑脱,但Release時,一定要關(guān)閉苍糠,因為App普遍沒有作為服務器的類型叁丧,會被拒審。
  • 避免在任何地方顯示“安卓岳瞭,Android拥娄,三星,華為瞳筏,微軟”等蘋果在各方面對手的名稱稚瘾,一旦發(fā)現(xiàn),肯定拒審姚炕。尤其是筆者開發(fā)過的IT新聞類App摊欠,上線時需要添加多個“蘋果競爭對手”過濾關(guān)鍵詞。筆者在填寫應用介紹時把自己的技術(shù)開發(fā)經(jīng)驗寫進去柱宦,“兩年安卓開發(fā)經(jīng)驗”直接被拒些椒,只能寫為“兩年卓卓經(jīng)驗”??????。
  • 由于資料的保密性掸刊,為保證通過審核免糕,App采用假注冊模式,本地注冊存儲模擬登錄忧侧。注冊成功后與游客登錄后權(quán)限相同石窑。
  • 憑借筆者多年拒審??過審經(jīng)驗,總結(jié)一個原則蚓炬。一定不要和蘋果硬懟松逊,讓你改你就改,讓你怎么改就怎么改试吁。實在不過就使一些障眼法唄棺棵。例如當年避免蘋果內(nèi)購也是用盡渾身解數(shù),最終也是只用支付寶支付熄捍,微信支付確實沒法避免烛恤。當年慕課網(wǎng)App可以完全規(guī)避,有沒有大佬指導如何做到的余耽。
image-9.png
image-10.png

三缚柏、Flutter、SwiftUI碟贾、Android(鴻蒙)的簡單思考

筆者打算將Flutter币喧、iOS轨域、Android、鴻蒙杀餐、小程序干发、快應用、RN等移動開發(fā)的未來發(fā)展單獨介紹分析史翘,奈何篇幅不夠枉长,現(xiàn)只做簡單闡述,稍后會發(fā)布另一篇文章仔細分析琼讽。

  • Flutter:混合開發(fā)必峰,我愿稱你為最強!從Flutter2.2性能提升來看钻蹬,如果性能再有進一步提升吼蚁,必定成為移動端開發(fā)主流,未來可期问欠。稍微吐槽下Dart肝匆,比Swift還是差點意思。
  • iOS:SwiftUI顺献,又快又靚又牛x术唬。成品效果驚艷,蘋果可謂是移動產(chǎn)品和技術(shù)的領(lǐng)導者滚澜。兩個缺點:①支持iOS 13以上,國內(nèi)開發(fā)環(huán)境來說嫁怀,還有一段路要走设捐。②成熟度不夠,雖然Swift已經(jīng)穩(wěn)定塘淑,寫起來十分便利萝招,但誰能知道SwiftUI會不會成為下一個SwiftUI。筆者從Swift2.2開始接觸存捺,一個版本一個新語言的痛苦至今猶在槐沼。
  • Android:移動市場最大蛋糕分割者。不限于手機捌治,目前最火的智能汽車市場也是以Android為主岗钩,選擇它肯定沒錯。國外Android流暢度接近iOS肖油,但國內(nèi)安卓你懂的兼吓,希望國內(nèi)推送統(tǒng)一聯(lián)盟盡快落地實用的標準和機制,避免社會資源的浪費森枪。
  • 鴻蒙:Fuchsia沒來视搏,鴻蒙它來了审孽。鑒于昨天OPPO公關(guān)評論鴻蒙事件,我只能??浑娜。前一陣與同事閑聊時佑力,談論過鴻蒙,我只是講出了一些實事筋遭,但他卻說我侮辱國產(chǎn)??打颤,這么大的罪名,我可擔待不起宛畦。畢竟用著國產(chǎn)的衣服鞋子桌子椅子食物水瘸洛,以后可不敢瞎評論。還是希望鴻蒙能夠崛起次和,少吹牛反肋,增加技術(shù)強度和提升產(chǎn)品體驗。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末踏施,一起剝皮案震驚了整個濱河市石蔗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畅形,老刑警劉巖养距,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異日熬,居然都是意外死亡棍厌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進店門竖席,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耘纱,“玉大人,你說我怎么就攤上這事毕荐∈觯” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵憎亚,是天一觀的道長员寇。 經(jīng)常有香客問我,道長第美,這世上最難降的妖魔是什么蝶锋? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮什往,結(jié)果婚禮上牲览,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好第献,可當我...
    茶點故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布贡必。 她就那樣靜靜地躺著,像睡著了一般庸毫。 火紅的嫁衣襯著肌膚如雪仔拟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天飒赃,我揣著相機與錄音利花,去河邊找鬼。 笑死载佳,一個胖子當著我的面吹牛炒事,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蔫慧,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼挠乳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姑躲?” 一聲冷哼從身側(cè)響起睡扬,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎黍析,沒想到半個月后卖怜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡阐枣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年马靠,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔼两。...
    茶點故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡虑粥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出宪哩,到底是詐尸還是另有隱情,我是刑警寧澤第晰,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布锁孟,位于F島的核電站,受9級特大地震影響茁瘦,放射性物質(zhì)發(fā)生泄漏品抽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一甜熔、第九天 我趴在偏房一處隱蔽的房頂上張望圆恤。 院中可真熱鬧,春花似錦腔稀、人聲如沸盆昙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽淡喜。三九已至秕磷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炼团,已是汗流浹背澎嚣。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瘟芝,地道東北人易桃。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像锌俱,于是被迫代替她去往敵國和親晤郑。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,592評論 2 353

推薦閱讀更多精彩內(nèi)容