flutter 怎么判断某个widge已经push并正在展示

在 Flutter 中,如果你使用的是 Navigator 来管理页面路由(即使用 Navigator.push 等方式),没有直接的内置 API 可以判断“某个 Widget 是否已经被 push 并正在展示”,因为:

  • Flutter 的导航是基于 Route 的,而不是基于 Widget 的。
  • 一个 Widget 是否“正在展示”取决于它是否在当前活动的 Route 中,并且该 Route 是否在导航栈的顶层。

那么我们怎么办呢?使用Navigator.pushNamed:

方法 1:使用 NavigatorObserver(全局监听)

你可以创建一个自定义的 NavigatorObserver,在其中记录当前显示的 Route:

class MyRouteObserver extends NavigatorObserver {
 // 单例代码略
  Route? currentRoute;

  @override
  void didPush(Route route, Route? previousRoute) {
    currentRoute = route;
    print('Pushed: ${route.settings.name}');
  }

  @override
  void didPop(Route route, Route? previousRoute) {
    currentRoute = previousRoute;
    print('Popped: ${route.settings.name}');
  }
}

然后在 MaterialApp 中注册它:

MaterialApp(
  navigatorObservers: [MyRouteObserver单例],
  // ...
);

之后你可以在任何地方访问 MyRouteObserver单例.currentRoute 来判断当前页面。

方法 3:使用 RouteAware(更精细控制)

Flutter 提供了 RouteAware 和 RouteObserver,可以让 Widget 自己感知生命周期:

class PageRouteObserver extends RouteObserver {
  String? currentRouteName;
  // 私有构造函数
  PageRouteObserver._internal();

  // 静态实例,Dart 中只会初始化一次
  static final PageRouteObserver _instance = PageRouteObserver._internal();

  // 工厂构造函数,返回唯一实例
  factory PageRouteObserver() => _instance;

  static PageRouteObserver get instance => _instance;
}

同样,别忘了在 MaterialApp 中注册 routeObserver:

MaterialApp(
  navigatorObservers: [routeObserver],
  // ...
)

再创建RouteAwareState


abstract class RouteAwareState<T extends StatefulWidget> extends State<T>
    with RouteAware {
  // push/pop life circle
  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    PageRouteObserver.instance.subscribe(this, ModalRoute.of(context)!);
  }

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

  @override
  void didPush() {
    // 当前页面被 push
    PageRouteObserver.instance.currentRouteName = ModalRoute.of(
      context,
    )?.settings.name;
  }

  @override
  void didPopNext() {
    // 从其他页面返回
    PageRouteObserver.instance.currentRouteName = ModalRoute.of(
      context,
    )?.settings.name;
  }

  @override
  void didPushNext() {
    // 跳转到其他页面
  }

  @override
  void didPop() {
    // 当前页面被 pop
  }
}

所有PageState继承RouteAwareState,StatelessWidget 原理也是一样。

最后使用方法如下:

 String? routeName = PageRouteObserver.instance.currentRouteName;

✅ 总结

方法 是否推荐 说明
NavigatorObserver ✅ 全局监听 适合跨页面逻辑
RouteAware ✅ 精细控制 适合 Widget 自己感知生命周期
判断某个 Widget 是否“正在展示” ❌ 不可行 Flutter 没有 Widget 层级的“展示”状态
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容