Flutter 如何实现监听路由 ?

实现除了登录页面其它页面如果没有登录状态则一律返回登录

阅读 3.1k
2 个回答

使用 navigatorObservers 获取界面跳转通知

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        // debugShowCheckedModeBanner: false,
        //添加navigator 观察者
        navigatorObservers: [CustObserver()],
        title: 'Flutter ',
        home: Scaffold(
          appBar: AppBar(
            title: const Text('Flutter'),
          ),
          body: const MyCuPageA(),
        ));
  }
}


class CustObserver extends NavigatorObserver {
  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    if (kDebugMode) {
      print('Observer');
    }
    
    //实现自己的逻辑

  }

  //还有很多很方法没有实现
}

使用自定义Navigator进行拦截

tools.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

extension Navigator0 on Navigator {
  static Future<T?> push<T extends Object?>(
      BuildContext context, Route<T> route) {
    if (kDebugMode) {
      print('拦截器');
    }

    return Navigator.of(context).push(route);
  }

  static Future<T?> pushNamed<T extends Object?>(
    BuildContext context,
    String routeName, {
    Object? arguments,
  }) {
    if (kDebugMode) {
      print('拦截器');
    }
     //这里实现自己的处理逻辑

    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }

  // other methods.......


}

// 下面这个也可以
class Navigator1 {

  static Future<T?> push<T extends Object?>(
      BuildContext context, Route<T> route) {
    if (kDebugMode) {
      print('拦截器');
    }
    return Navigator.of(context).push(route);
  }

  static Future<T?> pushNamed<T extends Object?>(
    BuildContext context,
    String routeName, {
    Object? arguments,
  }) {
    if (kDebugMode) {
      print('拦截器');
    }
    return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
  }
}

MyCuPageA

class MyCuPageA extends StatelessWidget {
  const MyCuPageA({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: CupertinoButton(
          child: const Text('Jump'),
          onPressed: () {
            // 使用自定义自定义Navigator
            Navigator0.push(context, MaterialPageRoute(builder: (ctx) {
              return const MyCuPageB();
            }));
          }),
    );
  }
}
  • 程序启动时候,判断本地是否存在accToken以及accToken是否过期
  • 如果accToken不存在或者过期,跳转登录界面
  • 如果accToken存在,跳转界面时候我们可以在自定义导航中检查accToken是否过期;在跳转到登录界面的时候可以使用下面方法

    popAndPushNamed<T extends Object?, TO extends Object?>(BuildContext context, String routeName, {TO? result, Object? arguments}) → Future<T?>
    Pop the current route off the navigator that most tightly encloses the given context and push a named route in its place.
  • 也可不用自定义导航器,根据每个接口返回的code判断当前是否应该重新去登录获取新的Token(比如每个接口中约定 code = 1时候需要去重新登录,code =0 返回正常数据)

https://api.flutter.dev/flutter/widgets/Navigator-class.html#constructors

用GetX 吧,每个页面的router 配置自定义middlewares就行了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题