flutter的导航和路由使用示例详解
作者:前端那些年 发布时间:2023-11-21 07:06:34
导航和路由
Flutter提供了一个完整的用于在屏幕之间导航和处理深层链接的系统。没有复杂深度链接的小型应用程序可以使用Navigator
,而具有特定深度链接和导航要求的应用程序也应该使用Router
来正确处理Android
和iOS
应用上的深度链接,并在应用程序在web上运行时与地址栏保持同步。
使用Navigator导航
Navigator
导航组可以用正确的过渡动画来展示对应的界面,当然,和web端的路由类似,界面其实也是以栈
的形式保存着。
通过路由的buildContext
上下文,并且调用对应的push()
或pop()
方法,我们就可以导航到新的界面,比如:
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SongScreen(song: song),
),
);
},
child: Text(song.name),
由于Navigator
保存了一个Route
对象的堆栈(表示历史堆栈),所以push()
方法也使用Route
对象作为参数。MaterialPageRoute
对象是Route
的子类,用于指定Material Design
的过渡动画。
命名路由
对于有些具有简单导航和深度链接需求的应用程序,我们可以使用Navigator
进行导航,使用MaterialApp
对象的routes
属性对路由进行配置:
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/details': (context) => DetailScreen(),
},
);
}
我们在这里配置的路由就是命名路由
。
命名路由的局限
尽管命名路由可以处理深层链接,但是他们的表现总是一致的,没办法做到自定义。当应用平台接收到一个新的深层链接,不论用户此时在哪个位置,Flutter都会将新的路线推送到导航器上。
使用命名路由的Flutter应用也不支持浏览器的前进按钮。基于这些原因,官方其实是不建议在大多数应用中使用命名路由。
当然,实际开发过程中,我们需要根据实际情况进行调整。
使用路由Router
具有高级导航和路由要求的Flutter应用程序(例如使用到每个屏幕的直接链接的web应用程序,或具有多个,或者嵌套导航Navigator
组件的应用程序)应使用诸如go_router
之类的路由包,该包可以在应用程序收到新的深度链接时解析路由路径并配置Navigator
。
要使用路由,我们需要切换到MaterialApp
或Cupertino App
上的路由器构造函数,并为其提供路由器配置。
MaterialApp.router(
routerConfig: GoRouter(
// …
)
);
由于像go_router
这样的包是声明性的,所以当接收到深度链接时,它们将始终显示相同的界面。
同时使用Router和Navigator
Router
和Navigator
在设计时就可以协同工作。我们可以使用像go_router
这样的路由包的 API进行路由的跳转,也可以使用Navigator
的push()
或pop()
方法进行导航。
当我们使用Router
或声明性路由包进行导航时,Navigator
上的每个路由页面都是支持的。这表示,路由是根据页面上的使用了页面上参数的Navigator
构造函数创建的路由。
相反,通过调用Navigator.push()
等方法的路由导航,将会在导航中添加一个pageless
(无页面)的路由。如果我们使用的是路由包,则页面支持的路由始终是可深度链接的,而无页面的路由则不是。
当从导航器中删除页面支持的路由时,它之后的所有无页面路由也将被删除。例如,如果深度链接通过从导航器中删除页面支持的路由来导航,则之后(直到下一个_pagebacked路由)的所有无页面路由也将被删除。
深度链接 Deep linking
Flutter支持iOS、Android和web浏览器上的深度链接。打开URL会在应用程序中显示该屏幕。通过以下步骤,我们可以使用命名路由(使用routes参数或onGenerateRoute)或使用Router小部件启动和显示路由。
如果我们在web浏览器中运行应用程序,则无需额外设置。路由路径的处理方式与iOS或Android深度链接相同。默认情况下,web应用程序使用模式:/#/path/to/app/screen
从url片段读取深度链接路径,但这可以通过配置应用程序的url策略来更改。
在 Android 上启用 深度链接 Deep linking
只需要在AndroidManifest.xml
配置文件中的<activity>
标签中添加一个元数据标签和意向过滤器标签即可:
<!-- 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>
配置之后,重启整个应用即可。
在 ios 上启用 深度链接 Deep linking
需要在ios/Runner
文件夹下Info.plist
文件中添加两个新的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
是一个唯一的URL,用于将我们的应用程序与其他使用相同方案的应用程序进行区分。
配置完成后,同样需要进行应用的重启。
在web上配置URL策略
flutter web 应用支持两种URL策略:
hash模式。如:
flutterexample.dev/#/path/to/screen
.path模式。如:
lutterexample.dev/path/to/screen
.
配置起来也很简单,从flutter_web_plugins插件库导入usePathUrlStrategy方法,在入口函数中调用即可。
import 'package:flutter_web_plugins/url_strategy.dart';
void main() {
usePathUrlStrategy();
runApp(ExampleApp());
}
PathUrlStrategy使用历史API,这需要对web服务器进行额外配置,具体怎么配置,应该跟nginx相关~
最后
熟悉了导航和路由,再加深一下对组件里的理解记忆,后面熟悉一下接口请求的方式,基本上就可以开始做flutter应用的开发了~
来源:https://juejin.cn/post/7182100050330255417


猜你喜欢
- JAVA中去掉空格 1. String.trim() trim()是去掉首尾空格 2.str
- 目录一、单例模式饿汉模式懒汉模式懒汉模式二、堵塞队列实现BlockingQueue三、定时器总结一、单例模式单例模式是一种设计模式,针对一些
- 本文大纲本文章将要介绍的内容有以下几点,读者朋友也可先自行思考一下相关问题:线程中断 interrupt 方法怎么理解,意思就是线程中断了吗
- 方案1.设置一个悬浮的视图挂在recycleView顶部,随着item的移动位置,悬浮标题自动跟随移动或者是保持原地不动。2.使用recyc
- 前言这几天正在看Android官方的开发文档,里面有很多很值得思考的开发建议,有时间的朋友可以去看一下(官方是英文文档,如果看不懂可以通过浏
- Java 读取外部资源的方法详解在Java代码中经常有读取外部资源的要求:如配置文件等等,通常会把配置文件放在classpath下或者在we
- 本文实例讲述了C#实现获取程序路径方法。分享给大家供大家参考。具体如下:获取DLL的目录:Assembly myAssembly = Ass
- 写在前面从Java 1.0开始,引入java.io包;到Java 1.4再扩展了java.nio包;再到java 1.7又添加了新的流类,使
- 好久没有写文章了,年前公司新开了一个项目,是和usb转串口通信相关的,需求是用安卓平板通过usb转接后与好几个外设进行通信,一直忙到最近,才
- 1. 插入排序步骤:1.从第一个元素开始,该元素可以认为已经被排序2.取下一个元素tem,从已排序的元素序列从后往前扫描3.如果该元素大于t
- 本文实例为大家分享了Android快速实现断点续传的具体代码,供大家参考,具体内容如下1.导入依赖compile 'com.loop
- java.lang.OutOfMemoryError处理错误java.lang.OutOfMemoryError异常解决方法原因: 常见的有
- 写在前面本文由markdown格式写成,为本人第一次这么写,排版可能会有点乱,还望各位海涵。 主要写的是使用Ribbon进行Res
- 什么是适配器模式? 适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不
- 1.概述Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。Spring MVC的特
- 一、前言在mybatis官网中,有插件一说 mybatis plugins 如果同时有多个插件,那么他们的执行顺序是怎样的?二、准备工作、代
- Java8对集合提供了一种流式计算的方式,这种风格将要处理的元素集合看 作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如
- 本文实例分析了C#中var关键字用法。分享给大家供大家参考。具体方法如下:C#关键字是伴随着.NET 3.5以后,伴随着匿名函数、LINQ而
- Java多态对象的类型转换这里所说的对象类型转换,是指存在继承关系的对象,不是任意类型的对象。当对不存在继承关系的对象进行强制类型转换时,j
- BufferedImage转换为MultipartFileJava里读取图片或调整图片大小可使用BufferedImage进行操作(参考我另