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.

Aller à l'installation

Informations de source

Dépôt
mono0926/route_observer_mixin
Dernière activité de la source
9 septembre 2026 à 03:05
Langue détectée de SKILL.md
anglais
Étoiles
26
Forks
5

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
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()`.
Voir sur GitHub