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.

Ir a la instalación

Datos de origen

Repositorio
mono0926/route_observer_mixin
Última actividad en el origen
9 de septiembre de 2026 a las 03:05
Idioma detectado de SKILL.md
inglés
Estrellas
26
Forks
5

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
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()`.
Ver en GitHub