Skip to main content

route-observer-mixin-route-awareness

Use when tracking Flutter screen navigation lifecycle events (screen focus, push, pop, backgrounding) using route_observer_mixin without boilerplate subscription management.

跳到安装

来源信息

仓库
mono0926/route_observer_mixin
最近来源活动
2026年9月9日 03:05
检测到的 SKILL.md 语言
英语
星标
26
分支
5

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
route_observer_mixin-route-awareness
description
Use when tracking Flutter screen navigation lifecycle events (screen focus, push, pop, backgrounding) using route_observer_mixin without boilerplate subscription management.
# route_observer_mixin Screen Tracking Guide `route_observer_mixin` eliminates manual registration and disposal of Flutter `RouteObserver` and `RouteAware` subscriptions. It provides clean, declarative hooks for page lifecycle transitions (`didPush`, `didPop`, `didPushNext`, `didPopNext`). ## Guidelines - **Setup in Navigator**: - Wrap your app with `RouteObserverProvider` above `MaterialApp` (or provide it via `provider` / `riverpod`). - Pass `RouteObserverProvider.of(context)` (or the provider's instance) to `MaterialApp.navigatorObservers`. - **Implementing in State**: - Add `with RouteAware, RouteObserverMixin` to the target `State<MyWidget>` class. - Implement lifecycle methods: - `didPush()`: Called when the screen has been pushed and is now visible. - `didPopNext()`: Called when the top route has been popped off, and this screen becomes visible again. - `didPushNext()`: Called when a new route is pushed on top of this screen (this screen becomes obscured). - `didPop()`: Called when this screen has been popped off the navigator. - **Analytics & Tracking**: - Track screen views inside `didPush()` and `didPopNext()` to accurately capture when the user returns to a previously viewed page. - **Lifecycle Cleanup**: - Do not manually call `routeObserver.unsubscribe(this)`. `RouteObserverMixin` automatically manages subscription registration in `didChangeDependencies` and unsubscription in `dispose`. ## Examples ### 1. App Setup ```dart import 'package:flutter/material.dart'; import 'package:route_observer_mixin/route_observer_mixin.dart'; void main() { runApp( RouteObserverProvider( child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( navigatorObservers: [ RouteObserverProvider.of(context), ], home: const HomeScreen(), ); } } ``` ### 2. Page Implementation with Analytics Tracking ```dart import 'package:flutter/material.dart'; import 'package:route_observer_mixin/route_observer_mixin.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State<HomeScreen> createState() => _HomeScreenState(); } class _HomeScreenState extends State<HomeScreen> with RouteAware, RouteObserverMixin { @override void didPush() { super.didPush(); // Screen is pushed for the first time _trackScreenView(); } @override void didPopNext() { super.didPopNext(); // User returned back to this screen from a pushed page _trackScreenView(); _refreshContent(); } @override void didPushNext() { super.didPushNext(); // Another screen was pushed on top of this screen _pauseMediaPlayback(); } void _trackScreenView() { debugPrint('Analytics: Screen viewed -> HomeScreen'); } void _refreshContent() { debugPrint('Refreshing active screen data'); } void _pauseMediaPlayback() { debugPrint('Pausing background video/audio'); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Home')), body: Center( child: ElevatedButton( onPressed: () => Navigator.of(context).push( MaterialPageRoute(builder: (_) => const DetailScreen()), ), child: const Text('Go to Details'), ), ), ); } } class DetailScreen extends StatelessWidget { const DetailScreen({super.key}); @override Widget build(BuildContext context) => Scaffold( appBar: AppBar(title: const Text('Details')), ); } ``` ## Common Pitfalls & Anti-Patterns - ❌ **Anti-pattern**: Manually managing `RouteObserver().subscribe(this, ModalRoute.of(context)!)` inside `didChangeDependencies`, which frequently leaks subscriptions if unsubscription is missed in `dispose`. - ✔️ **Correct**: Use `RouteObserverMixin`, which handles registration and unsubscription safely and deterministically. - ❌ **Anti-pattern**: Only tracking screen view analytics in `initState`, which fails to capture when users navigate back to the page via the back button. - ✔️ **Correct**: Track screen views in both `didPush()` and `didPopNext()`.
在 GitHub 查看