flutter - 如何使用路由处理 Flutter 中的深度链接
问题描述
我正在尝试构建深度链接功能,到目前为止,应用程序的初始启动和从深度链接中检索参数都很好。
但是,我在深度链接到应用程序后导航到屏幕时遇到问题。我该怎么做?
我的代码如下所示:
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
Uri _latestUri;
Object _err;
StreamSubscription _sub;
@override void initState() {
super.initState();
_handleIncomingLinks();
}
@override void dispose() {
_sub?.cancel();
super.dispose();
}
void _handleIncomingLinks() {
_sub = uriLinkStream.listen((Uri uri) {
if (!mounted) return;
print('got uri: $uri'); // printed: got uri: myapp://?key1=test
setState(() {
_latestUri = uri;
_err = null;
Navigator.pushNamed(context, 'login'); // This doesn't work because the context does not include navigator
});
}, onError: (Object err) {
if (!mounted) return;
print('got err: $err');
setState(() {
_latestUri = null;
if (err is FormatException) {
_err = err;
} else {
_err = null;
}
});
});
}
@override Widget build(BuildContext context) {
return MaterialApp(
initialRoute: 'splash-screen',
onGenerateRoute: (settings) {
switch (settings.name) {
case 'splash-screen':
return
PageTransition(
child: BlocProvider(
create: (context) => SplashScreenCubit(APIRepository(
apiClient: APIClient(httpClient: http.Client()))),
child: SplashScreen(),
),
type: PageTransitionType.rightToLeft,
settings: settings);
break;
case 'create-account':
return PageTransition(
child: BlocProvider(
create: (context) => CreateAccountScreenCubit(
APIRepository(
apiClient: APIClient(httpClient: http.Client()))),
child: CreateAccountScreen(),
),
type: PageTransitionType.rightToLeft,
settings: settings);
break;
case 'login':
return PageTransition(
child: BlocProvider(
create: (context) => LoginScreenCubit(APIRepository(
apiClient: APIClient(httpClient: http.Client()))),
child: LoginScreen(),
),
type: PageTransitionType.rightToLeft,
settings: settings);
break;
default:
return null;
},
);
}
}
解决方案
如果您需要的是能够在不获取上下文的情况下进行导航,Navigtor.of
因为您需要处理深度链接,您需要使用navigatorKey
属性,您可以在此处阅读详细信息。
那么您的代码将如下所示
void main() { ... }
class MyApp extends StatefulWidget { ... }
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
Uri _latestUri;
Object _err;
GlobalKey<NavigatorState> navigatorKey = GlobalKey();
StreamSubscription _sub;
@override void initState() { ... }
@override void dispose() { ... }
void _handleIncomingLinks() {
_sub = uriLinkStream.listen((Uri uri) {
if (!mounted) return;
print('got uri: $uri'); // printed: got uri: myapp://?key1=test
setState(() {
_latestUri = uri;
_err = null;
});
// use the navigatorkey currentstate to navigate to the page you are intended to visit
navigatorKey.currentState.pushNamedAndRemoveUntil('login', (route) => false);
}, onError: (Object err) { ... });
@override Widget build(BuildContext context) { ... }
}
推荐阅读
- php - 注入控制器中的函数有多少模型名称[基于问题]?
- unit-testing - Azure Dev Ops 构建管道 xunit 嵌套失败(.net 核心)
- java - 空 GETINPUTSTREAM
- java - Spring STOMP WebSocket 会话断开处理程序/重新连接处理
- java - 如何进一步调查内存泄漏
- android - 我应该在 BindAdapter 类中使用注入吗?
- python - 将文件作为附件发送 Django
- tensorflow - 对比损失函数的准确性在训练集上有所提高,但验证准确性变得更差或没有提高
- python - 是否可以在内联代码中使用“with”?
- mongodb - 如何使用 MongoDB-JAVA API 动态关闭模式验证