如何解决如何使用路由处理 Flutter 中的深层链接 addPostFrameCallback
我正在尝试构建深层链接功能,到目前为止,应用程序的初始启动和从深层链接中检索参数都进行得很顺利。
但是,我在深度链接到应用后导航到屏幕时遇到问题。我该怎么做?
我的代码如下:
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(),settings: settings);
break;
case 'login':
return PageTransition(
child: BlocProvider(
create: (context) => LoginScreenCubit(APIRepository(
apiclient: apiclient(httpClient: http.Client()))),child: LoginScreen(),settings: settings);
break;
default:
return null;
},);
}
}
解决方法
如果您需要的是能够在不从 Navigtor.of
获取上下文的情况下进行导航以处理深层链接,则需要使用 navigatorKey
属性,您可以阅读详细信息 {{3} }.
那么你的代码会是这样的
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) { ... }
}
,
您的深层链接流可以在 build 方法之前触发,但此时您不能调用 Navigator
。因此,您可以使用 addPostFrameCallback
提供的 SchedulerBinding
修复它:
addPostFrameCallback
在此帧结束时安排回调。
不请求新框架。
这个回调在一个帧期间运行,就在持久帧之后 回调(这是当主渲染管道已经 酡)。如果帧正在进行中并且帧后回调没有 还没有被执行,那么注册的回调仍然被执行 在帧期间。否则,执行注册的回调 在下一帧。
回调按添加顺序执行。
帧后回调不能取消注册。他们被准确地称为 一次。
...
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;
// Call your navigator inside addPostFrameCallback
WidgetsBinding.instance?.addPostFrameCallback((_) {
Navigator.pushNamed(context,'login');
});
});
},onError: (Object err) {
if (!mounted) return;
print('got err: $err');
setState(() {
_latestUri = null;
if (err is FormatException) {
_err = err;
} else {
_err = null;
}
});
});
}
...
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。