flutter - 从命名路由重定向用户

标签 flutter dart flutter-web mobile-development

因此,我有一个与问this older question的人类似的问题,但有不同的要求,那里的答案都无济于事。

当用户打开应用程序时,如果他们尚未登录,我希望他们与登录页面打招呼,如果已经登录,则希望他们回到主页(底部导航栏 View )。我可以在MaterialApp中定义如下:

MaterialApp(
  initialRoute: authProvider.isAuthenticated
      ? '/home'
      : '/login',
  routes: {
    '/home': (_) =>
        ChangeNotifierProvider<BottomNavigationBarProvider>(
            child: AppBottomNavigationBar(),
            create: (_) => BottomNavigationBarProvider()),
    '/login': (_) => LoginView()
  },
)

到现在为止还挺好。除了我希望它可以在网络上运行之外,现在,即使用户首次打开myapp.com时的默认屏幕是myapp.com/#/login,任何用户都可以通过简单地访问myapp.com/#/home来绕过登录屏幕。

现在,我尝试将用户重定向到底部导航栏的initState()中的登录页面(并将initialRoute设置为/home),但是在移动设备上这具有不良行为。

如果我尝试这样做:

void initState() {
  super.initState();

  if (!Provider.of<AuthProvider>(context, listen: false).isAuthenticated) {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      Navigator.of(context).pushNamed('/login');
    });
  }
}

然后只需按返回即可使用户返回首页,再次绕过登录。如果我尝试使用popAndPushNamed而不是仅推送,则按back将打开空白屏幕(而不是关闭应用程序)。

有什么方法可以正确执行此操作,使其在Web和移动设备上均可工作?

最佳答案

如果在窗口小部件类上使用 RouteAware mixin,则在导航到(或离开)它们时会收到通知。您可以使用它来检查用户是否应该在那里,如果不存在,可以将其导航:

要使用它,首先需要所有小部件类都可以访问的 RouteObserver 全局实例:

final routeObserver = RouteObserver<PageRoute>();

然后,您需要使用MaterialApp注册它:

MaterialApp(
  routeObservers: [routeObserver],
)

然后将您的小部件注册到路线观察者:

class HomeViewState extends State<HomeView> with RouteAware {
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    routeObserver.subscribe(this, ModalRoute.of(context));
  }

  @override
  void dispose() {
    routeObserver.unsubscribe(this);
    super.dispose();
  }

  void didPop() {
    // This gets called when this widget gets popped
  }

  void didPopNext() {
    // This gets called when another route gets popped making this widget visible
  }

  void didPush() {
    // This gets called when this widget gets pushed
  }

  void didPushNext() {
    // This gets called with another widget gets pushed making this widget hidden
  }

  ...
}

在您的情况下,如果用户错误地登录到登录页面,则可以使用didPush路由将其导航到登录页面:

void didPush() {
  if (checkLoginStateSomehow() == notLoggedIn) {
    Navigator.of(context).pushReplacementNamed('login');
  }
}

关于flutter - 从命名路由重定向用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60455094/

相关文章:

Flutter - 页面之间的持久化状态

dart - Flutter 菜单和导航

dart - 我无法添加 Text(installedApps[index] ["app_name"]) 因为 'index' 未定义。我怎样才能添加这个文本?

Flutter Web : How Do You Compress an Image/File?

java - startForeground 通知不显示标题或内容

flutter - 为什么 appBar 小部件在 flutter 中不恒定

firebase - Flutter - 如何集成自动推送通知

flutter - 如何修复行中间的 "right Overflowed by 39 Pixels error"?

android-studio - 坚持将文件同步到设备 Chrome... Flutter Web

flutter - 更改选项卡时如何获取Flutter ScrollController以保存ListView.builder()的位置?