flutter的導(dǎo)航和路由使用示例詳解
導(dǎo)航和路由
Flutter提供了一個(gè)完整的用于在屏幕之間導(dǎo)航和處理深層鏈接的系統(tǒng)。沒有復(fù)雜深度鏈接的小型應(yīng)用程序可以使用Navigator
,而具有特定深度鏈接和導(dǎo)航要求的應(yīng)用程序也應(yīng)該使用Router
來正確處理Android
和iOS
應(yīng)用上的深度鏈接,并在應(yīng)用程序在web上運(yùn)行時(shí)與地址欄保持同步。
使用Navigator導(dǎo)航
Navigator
導(dǎo)航組可以用正確的過渡動(dòng)畫來展示對(duì)應(yīng)的界面,當(dāng)然,和web端的路由類似,界面其實(shí)也是以棧
的形式保存著。
通過路由的buildContext
上下文,并且調(diào)用對(duì)應(yīng)的push()
或pop()
方法,我們就可以導(dǎo)航到新的界面,比如:
onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const SongScreen(song: song), ), ); }, child: Text(song.name),
由于Navigator
保存了一個(gè)Route
對(duì)象的堆棧(表示歷史堆棧),所以push()
方法也使用Route
對(duì)象作為參數(shù)。MaterialPageRoute
對(duì)象是Route
的子類,用于指定Material Design
的過渡動(dòng)畫。
命名路由
對(duì)于有些具有簡(jiǎn)單導(dǎo)航和深度鏈接需求的應(yīng)用程序,我們可以使用Navigator
進(jìn)行導(dǎo)航,使用MaterialApp
對(duì)象的routes
屬性對(duì)路由進(jìn)行配置:
@override Widget build(BuildContext context) { return MaterialApp( routes: { '/': (context) => HomeScreen(), '/details': (context) => DetailScreen(), }, ); }
我們?cè)谶@里配置的路由就是命名路由
。
命名路由的局限
盡管命名路由可以處理深層鏈接,但是他們的表現(xiàn)總是一致的,沒辦法做到自定義。當(dāng)應(yīng)用平臺(tái)接收到一個(gè)新的深層鏈接,不論用戶此時(shí)在哪個(gè)位置,F(xiàn)lutter都會(huì)將新的路線推送到導(dǎo)航器上。
使用命名路由的Flutter應(yīng)用也不支持瀏覽器的前進(jìn)按鈕。基于這些原因,官方其實(shí)是不建議在大多數(shù)應(yīng)用中使用命名路由。
當(dāng)然,實(shí)際開發(fā)過程中,我們需要根據(jù)實(shí)際情況進(jìn)行調(diào)整。
使用路由Router
具有高級(jí)導(dǎo)航和路由要求的Flutter應(yīng)用程序(例如使用到每個(gè)屏幕的直接鏈接的web應(yīng)用程序,或具有多個(gè),或者嵌套導(dǎo)航Navigator
組件的應(yīng)用程序)應(yīng)使用諸如go_router
之類的路由包,該包可以在應(yīng)用程序收到新的深度鏈接時(shí)解析路由路徑并配置Navigator
。
要使用路由,我們需要切換到MaterialApp
或Cupertino App
上的路由器構(gòu)造函數(shù),并為其提供路由器配置。
MaterialApp.router( routerConfig: GoRouter( // … ) );
由于像go_router
這樣的包是聲明性的,所以當(dāng)接收到深度鏈接時(shí),它們將始終顯示相同的界面。
同時(shí)使用Router和Navigator
Router
和Navigator
在設(shè)計(jì)時(shí)就可以協(xié)同工作。我們可以使用像go_router
這樣的路由包的 API進(jìn)行路由的跳轉(zhuǎn),也可以使用Navigator
的push()
或pop()
方法進(jìn)行導(dǎo)航。
當(dāng)我們使用Router
或聲明性路由包進(jìn)行導(dǎo)航時(shí),Navigator
上的每個(gè)路由頁面都是支持的。這表示,路由是根據(jù)頁面上的使用了頁面上參數(shù)的Navigator
構(gòu)造函數(shù)創(chuàng)建的路由。
相反,通過調(diào)用Navigator.push()
等方法的路由導(dǎo)航,將會(huì)在導(dǎo)航中添加一個(gè)pageless
(無頁面)的路由。如果我們使用的是路由包,則頁面支持的路由始終是可深度鏈接的,而無頁面的路由則不是。
當(dāng)從導(dǎo)航器中刪除頁面支持的路由時(shí),它之后的所有無頁面路由也將被刪除。例如,如果深度鏈接通過從導(dǎo)航器中刪除頁面支持的路由來導(dǎo)航,則之后(直到下一個(gè)_pagebacked路由)的所有無頁面路由也將被刪除。
深度鏈接 Deep linking
Flutter支持iOS、Android和web瀏覽器上的深度鏈接。打開URL會(huì)在應(yīng)用程序中顯示該屏幕。通過以下步驟,我們可以使用命名路由(使用routes參數(shù)或onGenerateRoute)或使用Router小部件啟動(dòng)和顯示路由。
如果我們?cè)趙eb瀏覽器中運(yùn)行應(yīng)用程序,則無需額外設(shè)置。路由路徑的處理方式與iOS或Android深度鏈接相同。默認(rèn)情況下,web應(yīng)用程序使用模式:/#/path/to/app/screen
從url片段讀取深度鏈接路徑,但這可以通過配置應(yīng)用程序的url策略來更改。
在 Android 上啟用 深度鏈接 Deep linking
只需要在AndroidManifest.xml
配置文件中的<activity>
標(biāo)簽中添加一個(gè)元數(shù)據(jù)標(biāo)簽和意向過濾器標(biāo)簽即可:
<!-- Deep linking --> <meta-data android:name="flutter_deeplinking_enabled" android:value="true" /> <intent-filter android:autoVerify="true"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="http" android:host="flutterbooksample.com" /> <data android:scheme="https" /> </intent-filter>
配置之后,重啟整個(gè)應(yīng)用即可。
在 ios 上啟用 深度鏈接 Deep linking
需要在ios/Runner
文件夾下Info.plist
文件中添加兩個(gè)新的key:
<key>FlutterDeepLinkingEnabled</key> <true/> <key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLName</key> <string>flutterbooksample.com</string> <key>CFBundleURLSchemes</key> <array> <string>customscheme</string> </array> </dict> </array>
CFBundleURLName
是一個(gè)唯一的URL,用于將我們的應(yīng)用程序與其他使用相同方案的應(yīng)用程序進(jìn)行區(qū)分。
配置完成后,同樣需要進(jìn)行應(yīng)用的重啟。
在web上配置URL策略
flutter web 應(yīng)用支持兩種URL策略:
- hash模式。如:
flutterexample.dev/#/path/to/screen
. - path模式。如:
lutterexample.dev/path/to/screen
.
配置起來也很簡(jiǎn)單,從flutter_web_plugins插件庫導(dǎo)入usePathUrlStrategy方法,在入口函數(shù)中調(diào)用即可。
import 'package:flutter_web_plugins/url_strategy.dart'; void main() { usePathUrlStrategy(); runApp(ExampleApp()); }
PathUrlStrategy使用歷史API,這需要對(duì)web服務(wù)器進(jìn)行額外配置,具體怎么配置,應(yīng)該跟nginx相關(guān)~
最后
熟悉了導(dǎo)航和路由,再加深一下對(duì)組件里的理解記憶,后面熟悉一下接口請(qǐng)求的方式,基本上就可以開始做flutter應(yīng)用的開發(fā)了~
以上就是flutter的導(dǎo)航和路由使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于flutter 導(dǎo)航路由的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android實(shí)現(xiàn)水平帶刻度的進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)水平帶刻度的進(jìn)度條,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04Android實(shí)現(xiàn)單頁面浮層可拖動(dòng)view的示例代碼
本篇文章主要介紹了Android實(shí)現(xiàn)單頁面浮層可拖動(dòng)view的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Android實(shí)現(xiàn)滑動(dòng)屏幕切換圖片
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)滑動(dòng)屏幕切換圖片,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08Android開發(fā)之ListView實(shí)現(xiàn)Item局部刷新
對(duì)于ListView數(shù)據(jù)的刷新大家都知道,改變Adapter的數(shù)據(jù)源,然后調(diào)用Adapter的notifyDateSetChanged()方法即可。通過本篇文章給大家詳細(xì)介紹Android開發(fā)之ListView實(shí)現(xiàn)Item局部刷新,感興趣的朋友一起學(xué)習(xí)吧2015-10-10Android實(shí)現(xiàn)拍照、選擇圖片并裁剪圖片功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)拍照、選擇圖片并裁剪圖片功能的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05Android實(shí)現(xiàn)圖片區(qū)域裁剪功能
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)圖片區(qū)域裁剪功能,調(diào)用相冊(cè)、拍照實(shí)現(xiàn)縮放、切割圖片,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12深入解析Android系統(tǒng)中應(yīng)用程序前后臺(tái)切換的實(shí)現(xiàn)要點(diǎn)
這篇文章主要介紹了Android系統(tǒng)中應(yīng)用程序前后臺(tái)切換的實(shí)現(xiàn)要點(diǎn),除了切換操作的效果之外還重點(diǎn)講解了判斷程序運(yùn)行于前臺(tái)還是后臺(tái)的方法,需要的朋友可以參考下2016-04-04Android使用NestedScrollView?內(nèi)嵌RecycleView滑動(dòng)沖突問題解決
這篇文章主要介紹了Android使用NestedScrollView?內(nèi)嵌RecycleView滑動(dòng)沖突問題解決,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06Android編程中activity啟動(dòng)時(shí)出現(xiàn)白屏、黑屏問題的解決方法
這篇文章主要介紹了Android編程中activity啟動(dòng)時(shí)出現(xiàn)白屏、黑屏問題的解決方法,涉及Android針對(duì)activity啟動(dòng)設(shè)置的技巧,需要的朋友可以參考下2015-12-12Android自定義引導(dǎo)玩轉(zhuǎn)ViewPager的方法詳解
這篇文章主要給大家介紹了關(guān)于Android自定義引導(dǎo)玩轉(zhuǎn)ViewPager的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06