原文地址:
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)問題集侯,解決問題。
注:Android license status unknown的警告是因為我本地java版本過高帜消,不影響開發(fā)棠枉,可以忽略。
當然泡挺,也可以使用Visual Studio開發(fā)辈讶,開發(fā)Windows程序必選。并且編譯打包EXE文件時娄猫,必須在Windows10電腦環(huán)境運行荞估。
(所以筆者在項目收尾階段安裝Windows10虛擬機并安裝VS后才能打包,占用我電腦40G的存儲稚新。??????)
②推薦一些學習Flutter的學習資料網(wǎng)站:
- Flutter中文網(wǎng):https://flutterchina.club
字節(jié)跳動-幸福里FE團隊某大神制作,入門最佳選擇跪腹,保姆級資料褂删。
- Flutter官網(wǎng):https://flutter.dev,官網(wǎng)中文:https://flutter.cn
官網(wǎng)資料冲茸,最為可靠屯阀。版本新缅帘,資源全,手把手視頻教學及在線練習體驗难衰。
- 未曾相識的老孟大哥:http://laomengit.com
最全的中文控件庫钦无,使用與需求更貼切的良心官方控件,省時省心又省力盖袭。
吐槽一下用Android寫UI失暂,Android(ListView,RecycleView)輸于iOS(UITableView,UICollectionView)的原因,就是iOS基本不需要自定義適配器鳄虱。但Android使用XML寫UI弟塞,非常方便,強于Xib拙已。
- 第三方控件庫:https://pub.flutter-io.cn
相當于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
- 阿里Flutter-GO:https://github.com/alibaba/flutter-go
值得推薦错洁,以成品介紹組件〗渫唬可惜的是可能是因為《閑魚》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-desktop
及flutter 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ù)、背景顏色進行封裝产雹。代碼篇幅較長诫惭,以圖片替代展示。
②整體布局的思路
- 標題搜索欄以外層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ù)藏雏。
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集成的第三方庫有:
- 常用功能及第三方庫列表
- 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)限,并啟動原生文件保存窗口寻狂。這也是審核被拒的重要原因岁经。
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ī)避,有沒有大佬指導如何做到的余耽。
三缚柏、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)品體驗。