這里我們以錢包項(xiàng)目舉例
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了安福免費(fèi)建站歡迎大家使用!
我們先建一個(gè)文件夾 Wallets 用來存放所有錢包項(xiàng)目需要聯(lián)調(diào)的 Module 。如下圖我們將所有需要聯(lián)調(diào)的 Module 都存放到 Wallets 文件夾中。
做好上面的上面的準(zhǔn)備后,我們用AS打開Wallets 文件夾,此時(shí)AS導(dǎo)航欄側(cè)我們看到所有需要聯(lián)調(diào)的子Module都在這里了
這時(shí)我們看到AS找不我們的入口文件
所以我們需要給AS設(shè)置一下,告訴AS我們的入口文件在哪里,點(diǎn)擊上圖紅框選中的部分彈出下面的對(duì)話框
點(diǎn)擊上圖中箭頭指向的+,彈出下面對(duì)話框
選擇展開所有列表,選中Flutter,如下圖所示
在彈出的對(duì)話框中按圖中標(biāo)注的操作
在彈出的對(duì)話框中按圖中標(biāo)注的操作
上面操作都完成之后回到下面的對(duì)話框可以看到Fix已經(jīng)沒有了,然后再按下圖中所示操作
都操作好后就回到了AS開發(fā)主界面了,可以看到主界面上的入口文件已經(jīng)顯示了,運(yùn)行按鈕也可以點(diǎn)擊了
新建一個(gè)Flutter工程,android模塊。
1,只有一個(gè)Activity組件,它是Dart層繪制Widget的容器。
2,Application配置FlutterApplication。
應(yīng)用Application配置io.flutter.app.FlutterApplication類,App首次啟動(dòng)時(shí),初始化。
調(diào)用FlutterMain.startInitialization()方法。
initConfig方法,從AndroidManfest.xml配置的applicaion節(jié)點(diǎn)獲取meta-data數(shù)據(jù),初始化以下默認(rèn)值。
這些值都是使用中用到的name,例如,抽取apk中asset資源時(shí),flutter_assets打包目錄,打包產(chǎn)物data名稱。
initResources方法, 初始化資源。
在Flutter打包apk的asset目錄下,包括fluttter_asset目錄/資源項(xiàng),將資源從apk中抽取,保存在 Context.getDir("flutter", 0) 目錄下。
/data/user/0/包名/app_flutter目錄。
在目錄中創(chuàng)建一個(gè)時(shí)間戳文件,根據(jù)apk版本和包信息記錄的lastUpdateTime更新時(shí)間,第二次啟動(dòng)時(shí),若apk未更新,不需要再次抽取。
加載so庫,libflutter.so,System.loadLibrary()。
主頁面繼承FlutterActivity,配置啟動(dòng)模式singleTop。
FlutterActivity類在io.flutter.app包, (區(qū)別io.flutter.embedding.android包), 組件生命周期委托給FlutterActivityDelegate類。
組件啟動(dòng),onCreate方法。
FlutterMain.ensureInitializationComplete方法,確保資源成功抽取完成,創(chuàng)建FlutterView視圖(io.flutter.view),繼承SurfaceView類,setContentView方法,設(shè)置組件主布局即FlutterView視圖。
最后,根據(jù)Bundle路徑,runBundle()加載運(yùn)行,
調(diào)用FlutterView的runFromBundle方法,入口點(diǎn)在dart的main方法,
通過FlutterNativeView,調(diào)用FlutterJNI的native方法。
nativeRunBundleAndSnapshotFromLibrary方法。
任重而道遠(yuǎn)
Dart的 IO 庫包含了文件讀寫的相關(guān)類,它屬于 Dart 語法標(biāo)準(zhǔn)的一部分,所以通過 Dart IO 庫,無論是 Dart VM 下的腳本還是 Flutter,都是通過 Dart IO 庫來操作文件的,不過和 Dart VM 相比,F(xiàn)lutter 有一個(gè)重要差異是文件系統(tǒng)路徑不同,這是因?yàn)镈art VM 是運(yùn)行在 PC 或服務(wù)器操作系統(tǒng)下,而 Flutter 是運(yùn)行在移動(dòng)操作系統(tǒng)中,他們的文件系統(tǒng)會(huì)有一些差異。
Android 和 iOS 的應(yīng)用存儲(chǔ)目錄不同, PathProvider 插件提供了一種平臺(tái)透明的方式來訪問設(shè)備文件系統(tǒng)上的常用位置。該類當(dāng)前支持訪問兩個(gè)文件系統(tǒng)位置:
File代表一個(gè)整體的文件,他有三個(gè)構(gòu)造函數(shù),分別是:
文件讀取本身有兩種形式,一種是文本,一種是二進(jìn)制。
2.2.1 讀取文本內(nèi)容
如果是文本文件,F(xiàn)ile提供了readAsString、readAsLines、readAsStringSync、readAsLinesSync方法,讀取文本內(nèi)容
readAsString 一次性讀取所有文本
readAsLines 一行行的讀取文本
結(jié)果返回的是一個(gè)List,list中表示文件每行的內(nèi)容
readAsStringSync、readAsLinesSync同步讀取文本
2.2.2 讀取二進(jìn)制內(nèi)容
如果文件是二進(jìn)制,那么可以使用readAsBytes或者同步的方法readAsBytesSync:
dart中表示二進(jìn)制有一個(gè)專門的類型叫做Uint8List,他實(shí)際上表示的是一個(gè)int的List。
上面提到的讀取方式,都是一次性讀取整個(gè)文件,缺點(diǎn)就是如果文件太大的話,可能造成內(nèi)存空間的壓力。
所以File為我們提供了另外一種讀取文件的方法,流的形式來讀取文件.
示例
dart提供了open和openSync兩個(gè)方法來進(jìn)行隨機(jī)文件讀寫:
寫入和文件讀取一樣,可以一次性寫入或者獲得一個(gè)寫入句柄,然后再寫入。
一次性寫入的方法有四種,分別對(duì)應(yīng)字符串和二進(jìn)制
句柄形式可以調(diào)用openWrite方法,返回一個(gè)IOSink對(duì)象,然后通過這個(gè)對(duì)象進(jìn)行寫入:
默認(rèn)情況下寫入是會(huì)覆蓋整個(gè)文件的,但是可以通過下面的方式來更改寫入模式:
雖然dart中所有的異常都是運(yùn)行時(shí)異常,但是和java一樣,要想手動(dòng)處理文件讀寫中的異常,則可以使用try,catch:
我們還是以計(jì)數(shù)器為例,實(shí)現(xiàn)在應(yīng)用退出重啟后可以恢復(fù)點(diǎn)擊次數(shù)。 這里,我們使用文件來保存數(shù)據(jù):
1.引入PathProvider插件;在pubspec.yaml文件中添加如下聲明:
執(zhí)行 flutter pub get
2.實(shí)現(xiàn)如下
參考:
path_provider是flutter提供的一個(gè)獲取應(yīng)用存儲(chǔ)路徑的插件,它封裝了統(tǒng)一的api來獲取Android和ios兩個(gè)平臺(tái)的應(yīng)用存儲(chǔ)路徑,提供的api如下:
getTemporaryDirectory():獲取應(yīng)用臨時(shí)文件夾,該文件夾用來保存應(yīng)用的緩存,可以隨時(shí)刪除用于清緩存,對(duì)應(yīng)于Android的getCacheDir()和ios的NSTemporaryDirectory();
getApplicationDocumentsDirectory():獲取應(yīng)用安裝路徑,在應(yīng)用被卸載的時(shí)候刪除,對(duì)應(yīng)Android的AppDate目錄和iOS的NSDocumentDirectory目錄;
getExternalStorageDirectory():獲取存儲(chǔ)卡目錄,僅支持Android;
我們通過File和Directory來創(chuàng)建文件和文件夾時(shí)首先要獲取到應(yīng)用的相關(guān)路徑,不然會(huì)報(bào)錯(cuò);
File對(duì)象和Directory對(duì)象封裝在dart:io中,使用時(shí)需要先引入該庫:
Directory對(duì)象提供listSync()方法獲取文件夾里的內(nèi)容,該方法返回一個(gè)數(shù)組;
文件和文件夾都通過delete刪除,delete異步,deleteSync同步;如果一個(gè)文件夾是非空的刪除會(huì)報(bào)錯(cuò),刪除非空文件夾需要先清空該文件夾:
flutter對(duì)json序列化需要引入 dart:convert 庫:
通過jsonEncode/jsonDecode來轉(zhuǎn)換json對(duì)象:
// 將test目錄下的info.json復(fù)制到test2目錄下的info2.json中
引入包archive包:
壓縮:
壓縮前使用ZipFileEncoder先聲明處理壓縮的對(duì)象,調(diào)用該對(duì)象的zipDirectory方法壓縮文件,該方法接受兩個(gè)參數(shù),第一個(gè)是要壓縮文件/文件夾的路徑,第二個(gè)是壓縮包的保存路徑;
解壓:
當(dāng)在flutter中做一個(gè)全局的Toast,loading,Alert的時(shí)候,會(huì)使用到OverlayEntry,只要通過OverlayState.insert()就能展示在界面上。如此好用那OverlayState又是從哪來的呢?
首先,獲取OverlayState可以直接調(diào)用OverlayState overlayState = Overlay.of(context);直接就拿context去找了:OverlayState result = context.findAncestorStateOfTypeOverlayState();?
能找到?怎么就找到了呢
那看下Overlay的注釋:
盡管您可以直接創(chuàng)建一個(gè)[Overlay],但最常見的是使用[WidgetsApp]或[MaterialApp]中的[Navigator]創(chuàng)建的。導(dǎo)航器使用其overlay來管理路由的視覺外觀。
其中很關(guān)鍵的點(diǎn)在Navigator,那去找Navigator,順便還找到了Route。
Navigator中一層結(jié)構(gòu)就是Overlay。那看下Flutter中導(dǎo)航到底是怎么做的。
許多應(yīng)用程序在其小部件層次結(jié)構(gòu)的頂部附近都有一個(gè)導(dǎo)航器,以便使用[Overlay]來顯示它們的邏輯歷史,其中最近訪問的頁面可視化地位于較舊頁面的頂部。通過使用此模式,導(dǎo)航器可以通過在覆蓋圖中移動(dòng)小部件從一個(gè)頁面可視地過渡到另一個(gè)頁面。
既然Overlay從導(dǎo)航而來,那App中怎么就有導(dǎo)航呢?
Flutter創(chuàng)建的的時(shí)候,main里面的入口runApp(),在視圖的最底層會(huì)寫一個(gè)MaterialApp().
找到MaterialApp。
那就找在哪創(chuàng)建了Navigator。沒找到,但是在return時(shí)用的是WidgetsApp,看下介紹。
WidgetsApp定義了基本的應(yīng)用程序元素,但不依賴于Material庫,也就是MaterialApp是對(duì)WidgetsApp的上層封裝,為我們集成了Material元素。繼續(xù)找WidgetsApp。
在build里面創(chuàng)建了Navigator。
那么流程就是:MaterialApp ——?WidgetsApp ——?Navigator。
Overlay.of(context)拿到了Navigator里面的OverlayState.
首先查看入口函數(shù):
類MyApp:
MyHomePage:
state:
build:
此demo頁面涉及到兩個(gè)組件:圖片和icon。在這里做一個(gè)簡(jiǎn)單的介紹,更詳細(xì)的學(xué)習(xí)請(qǐng)參考flutter官網(wǎng)和相關(guān)書籍
在flutter中,我們可以通過Image組件來加載并顯示圖片,Image的數(shù)據(jù)源可以是asset、文件、內(nèi)存以及網(wǎng)絡(luò)。
ImageProvider 是一個(gè)抽象類,主要定義了圖片數(shù)據(jù)獲取的接口 load() ,從不同的數(shù)據(jù)源獲取圖片需要實(shí)現(xiàn)不同的 ImageProvider ,如 AssetImage 是實(shí)現(xiàn)了從Asset中加載圖片的ImageProvider,而 NetworkImage 實(shí)現(xiàn)了從網(wǎng)絡(luò)加載圖片的ImageProvider。
Image也提供了一個(gè)快捷的構(gòu)造函數(shù) Image.asset 用于從asset中加載、顯示圖片:
Image也提供了一個(gè)快捷的構(gòu)造函數(shù) Image.network 用于從網(wǎng)絡(luò)加載、顯示圖片:
Flutter中,可以像web開發(fā)一樣使用iconfont,iconfont也即"字體圖標(biāo)",它是將圖標(biāo)做成字體文件,然后通過指定不同的字符而顯示不同的圖片。
加號(hào)為圖片組件,減一為icon組件。點(diǎn)擊加號(hào),數(shù)字加1;點(diǎn)擊-1,數(shù)字減少1。