如何在颤振应用程序中无上下文导航?

Posted

技术标签:

【中文标题】如何在颤振应用程序中无上下文导航?【英文标题】:How to navigate without context in flutter app? 【发布时间】:2019-03-28 11:06:19 【问题描述】:

我有一个使用 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"]),
      ),
    );
  
);

我能够在第一次打开应用程序时实现这一点,但它只会打开主页如果我关闭应用程序,即使我重新打开它。我猜那是因为上下文发生了变化。

请帮忙!!

【问题讨论】:

【参考方案1】:

看这里: https://github.com/brianegan/flutter_redux/issues/5#issuecomment-361215074

您可以为导航设置全局键:

final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();

将其传递给 MaterialApp:

new MaterialApp(
      title: 'MyApp',
      onGenerateRoute: generateRoute,
      navigatorKey: navigatorKey,
    );

推送路线:

navigatorKey.currentState.pushNamed('/someRoute');

【讨论】:

navigatorKey 未定义 像魅力一样工作..!!谢谢兄弟。 @temirbek 在您的 main.dart 中定义 navigatorKey 并将其导入您的其他文件中。 另外,将MaterialApp的navigatorKey属性设置为声明的全局键(navigatorKey),而不是MaterialApp的key属性 @Mustafa 你能提供样品吗?我已经阅读了许多博客和论坛都提供相同的解决方案,但导航键可以从我的 dio 拦截器访问。【参考方案2】:

你可以使用这个很棒的插件: 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.

【讨论】:

这个包太棒了!谢谢! 那个包裹是救命稻草!【参考方案3】:

如果您想使用 globalKey 导航或显示没有上下文的对话框,尤其是使用 Bloc 或当您的逻辑与 UI 部分分离时,此解决方案是通用的。

首先安装这个包:

不是:我使用的是空安全版本

  get_it: ^7.2.0

然后为您的服务定位器创建一个单独的文件:

service_location.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'),
              ),
            ));
  
    

ma​​in.dart 上:

void main() 
  WidgetsFlutterBinding.ensureInitialized();
  NavigationService().setupLocator();
  runApp(MyApp());

// add navigatorKey for MaterialApp

 MaterialApp(
        navigatorKey: locator<NavigationService>().navigatorKey,
      ),

在您的业务逻辑文件 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

    

不是:我正在使用 generateRoute 进行路由。

【讨论】:

【参考方案4】:

您实际上可以通过将参数值添加到方法中来将上下文传递到 builder() 之外。

例如,如果您需要在没有构建器的情况下在 dart 文件中使用导航器推送。

你可以这样做

methodName(String name, String address, context)
Navigator.pushNamed(context, '/login');

【讨论】:

他在问如何在没有上下文的情况下导航。您的答案是另一种导航方式,但它仍然使用上下文。 为我工作。我不知道有一种方法可以使用这样的上下文进行导航。非常感谢:)

以上是关于如何在颤振应用程序中无上下文导航?的主要内容,如果未能解决你的问题,请参考以下文章

无上下文的颤振本地化

颤振导航未定义的“上下文”

双击按钮时如何修复颤振中的多个导航

如何从 Android 活动导航到特定的颤振路线?

如何安全地导航到我的颤振应用程序的默认路由(“主页”)?

颤振错误:'上下文!= null':不正确