关于路由监听

来源:16-9 登录模块MVVM架构模式改造-

Daniyar

2025-01-13

老师好!有些页面需要用户登录后才能让用户访问,有些页面不需要。在路由跳转或者页面切换的时候如何全局监听并且判断用户登录状态?如果用户没有登录那就跳回登录页面,让用户登录后再访问。

写回答

1回答

CrazyCodeBoy

2025-01-14

在 Flutter 中实现路由跳转时全局监听并判断用户的登录状态,可以通过自定义 NavigatorObserver 和结合登录状态进行控制。以下是具体的实现方案:


---

实现步骤

1. 创建一个全局登录状态管理

可以使用 Provider、GetX 或 Riverpod 等状态管理工具来维护用户的登录状态。这里以简单的全局变量为例:

bool isLoggedIn = false; // 用户登录状态

2. 自定义 NavigatorObserver

创建一个自定义的 NavigatorObserver 来监听路由变化。

class AuthNavigatorObserver extends NavigatorObserver {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPush(route, previousRoute);

    // 检查用户是否需要登录
    if (_requiresAuth(route.settings.name) && !isLoggedIn) {
      // 跳转到登录页
      navigator?.pushReplacementNamed('/login');
    }
  }

  bool _requiresAuth(String? routeName) {
    // 定义需要登录的路由
    const authRoutes = ['/protectedPage1', '/protectedPage2'];
    return authRoutes.contains(routeName);
  }
}

3. 在 MaterialApp 中配置

将自定义的 AuthNavigatorObserver 添加到 MaterialApp 中。

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorObservers: [AuthNavigatorObserver()],
      routes: {
        '/': (context) => HomePage(),
        '/login': (context) => LoginPage(),
        '/protectedPage1': (context) => ProtectedPage1(),
        '/protectedPage2': (context) => ProtectedPage2(),
      },
    );
  }
}

4. 登录成功后的处理

在用户登录成功后,更新登录状态,并跳转到之前想要访问的页面。

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('登录')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            isLoggedIn = true; // 更新登录状态
            Navigator.pushReplacementNamed(context, '/');
          },
          child: Text('登录'),
        ),
      ),
    );
  }
}

5. 配置无需登录的页面

在 _requiresAuth 方法中,排除无需登录的页面。


---

效果

1. 用户未登录时访问受保护的页面,会自动跳转到登录页。


2. 登录成功后,用户可以正常访问受保护的页面。


3. 无需登录的页面不会受影响。




---

如果需要更复杂的逻辑(如保存重定向路径、弹出提示框等),可以在 didPush 方法中进一步扩展逻辑。

0
0

慕课甄选-Flutter零基础极速入门到进阶实战

全新Flutter从入门到进阶,实战仿携程网App

661 学习 · 316 问题

查看课程