我有一个应用程序可以使用OneSignal接收推送通知。我做了一个通知打开处理程序,应在单击通知时打开特定的屏幕。我如何导航到没有上下文的屏幕。或如何在应用启动时打开特定屏幕。我的代码:
OneSignal.shared.setNotificationOpenedHandler((notification) {
var notify = notification.notification.payload.additionalData;
if (notify["type"] == "message") {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DM(user: notify['id']),
),
);
}
if (notify["type"] == "user") {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Profileo(notify["id"]),
),
);
}
if (notify["type"] == "post") {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => ViewPost(notify["id"]),
),
);
}
});
Run Code Online (Sandbox Code Playgroud)
首次打开该应用程序时,我可以实现此目的,但是,即使我关闭了该应用程序,即使重新打开它也只能打开主页。我想那是因为上下文已更改。
请帮忙!!
y.s*_*gan 27
你可以使用这个很棒的插件:https : //pub.dev/packages/get
来自包的描述:一个一致的导航库,允许您在没有上下文的情况下从代码中的任何位置在屏幕之间导航、打开对话框和显示小吃栏。
Get.to(NextScreen()); // look at this simplicity :)
Get.back(); // pop()
Get.off(NextScreen()); // clears the previous routes and opens a new screen.
Run Code Online (Sandbox Code Playgroud)
小智 12
在这里看这个:https : //github.com/brianegan/flutter_redux/issues/5#issuecomment-361215074
您可以为导航设置全局键:
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
Run Code Online (Sandbox Code Playgroud)
将其传递给MaterialApp:
new MaterialApp(
title: 'MyApp',
onGenerateRoute: generateRoute,
navigatorKey: navigatorKey,
);
Run Code Online (Sandbox Code Playgroud)
推送路线:
navigatorKey.currentState.pushNamed('/someRoute');
Run Code Online (Sandbox Code Playgroud)
jos*_*oid 11
最快的修复方法是使用全局navigatorKey(如 @tsdevelopment 回答)。要修复 undefined navigatorKey,必须从实例化它的位置导入它(对于本例中的示例main.dart)。
你的main.dart
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(CupertinoApp(
title: 'Navigate without context',
initialRoute: '/',
navigatorKey: navigatorKey, // important
onGenerateRoute: ...
));
}
Run Code Online (Sandbox Code Playgroud)
例如你在你的lib/utils/api.dart
import 'package:your_package_name/main.dart'; // important
abstract class API {
static Future<dynamic> get() async {
// call some api
...
// then you want to navigate to specific screen like login
navigatorKey.currentState?.pushNamed('/login'); // navigate to login, with null-aware check
}
}
Run Code Online (Sandbox Code Playgroud)
如果您喜欢服务方法,还可以提供一个要点示例。检查这个:https://gist.github.com/josephdicdican/81e59fad70530eac251ad6c28e2dcd4b
如果您想使用 globalKey 在没有上下文的情况下导航或显示对话框,尤其是使用 Bloc 或当您的逻辑与 UI 部分分离时,此解决方案是通用的。
首先安装这个包:
不:我使用的是空安全版本
get_it: ^7.2.0
Run Code Online (Sandbox Code Playgroud)
然后为您的服务定位器创建一个单独的文件:
服务位置.dart
import 'package:get_it/get_it.dart';
GetIt locator = GetIt.instance;
class NavigationService {
final GlobalKey<NavigatorState> navigatorKey =
new GlobalKey<NavigatorState>();
Future<dynamic> navigateTo(String routeName) {
return navigatorKey.currentState!.pushNamed(routeName);
}
void setupLocator() {
locator.registerLazySingleton(() => NavigationService());
}
void showMyDialog() {
showDialog(
context: navigatorKey.currentContext!,
builder: (context) => Center(
child: Material(
color: Colors.transparent,
child: Text('Hello'),
),
));
}
}
Run Code Online (Sandbox Code Playgroud)
在 main.dart上:
void main() {
WidgetsFlutterBinding.ensureInitialized();
NavigationService().setupLocator();
runApp(MyApp());
}
// add navigatorKey for MaterialApp
MaterialApp(
navigatorKey: locator<NavigationService>().navigatorKey,
),
Run Code Online (Sandbox Code Playgroud)
在您的业务逻辑文件bloc.dart中 ,在 bloc 类中或您想要在其中使用导航的任何类中定义它,然后开始在其中的任何函数中导航。
class Cubit extends Cubit<CubitState> {
final NavigationService _navigationService = locator<NavigationService>();
void sampleFunction(){
_navigationService.navigateTo('/home_screen'); // to navigate
_navigationService.showMyDialog(); // to show dialog
}
}
Run Code Online (Sandbox Code Playgroud)
不是:我使用generateRoute 进行路由。
| 归档时间: |
|
| 查看次数: |
3944 次 |
| 最近记录: |