[TIL] 20241220_Navigation Logger

ds-k.dev·2024년 12월 20일
0

TIL

목록 보기
25/26

개발을 진행하면서, Navigation의 stack 상태를 볼수 있다면 좋다는 생각이 들었고,
찾아보니 내장으로 NavigatorObserver라는 클래스가 있었다.

class NavigatorObserver {
  NavigatorState? get navigator => _navigators[this];

  static final Expando<NavigatorState> _navigators = Expando<NavigatorState>();

  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) { }

  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) { }

  void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) { }

  void didReplace({ Route<dynamic>? newRoute, Route<dynamic>? oldRoute }) { }

  void didStartUserGesture(Route<dynamic> route, Route<dynamic>? previousRoute) { }

  void didStopUserGesture() { }
}

이런 내장 클래스가 있는데, 각각의 내용은

1. didPush:

  • 의미: 새로운 라우트가 내비게이터에 추가(push) 되었을 때 호출됩니다.
  • 사용 예시: 새 화면이 열릴 때 이벤트를 기록하거나 애니메이션을 트리거할 때.
  • 매개변수:
    • route: 새로 추가된 라우트.
    • previousRoute: 바로 아래에 있던 이전 라우트(없을 수도 있음).

2. didPop:

  • 의미: 현재 활성화된 라우트가 제거(pop) 되었을 때 호출됩니다.
  • 사용 예시: 뒤로 가기 버튼이 눌리거나, 라우트를 닫는 작업 후 정리할 작업.
  • 매개변수:
    • route: 제거된 라우트.
    • previousRoute: 이제 활성화된 새 라우트(없을 수도 있음).

3. didRemove:

  • 의미: 내비게이터에서 라우트가 강제로 제거(remove) 되었을 때 호출됩니다.
  • 사용 예시: 특정 라우트를 강제로 닫았을 때 후속 작업을 처리.
  • 매개변수:
    • route: 제거된 라우트.
    • previousRoute: 제거된 라우트 아래에 있는 라우트(없을 수도 있음).

4. didReplace:

  • 의미: 기존 라우트가 새 라우트로 대체(replace) 되었을 때 호출됩니다.
  • 사용 예시: 화면을 교체하는 경우 데이터를 갱신하거나 이벤트를 처리.
  • 매개변수:
    • newRoute: 새로 대체된 라우트.
    • oldRoute: 기존의 대체된 라우트.

5. didStartUserGesture:

  • 의미: 사용자가 제스처를 통해 내비게이션 이동(예: 뒤로 가기)을 시작했을 때 호출됩니다.
  • 사용 예시: iOS의 스와이프 백(back) 제스처와 같은 사용자 입력을 감지.
  • 매개변수:
    • route: 현재 활성화된 라우트.
    • previousRoute: 이동 중 활성화될 라우트(없을 수도 있음).

6. didStopUserGesture:

  • 의미: 사용자 제스처를 통한 내비게이션 이동이 종료되었을 때 호출됩니다.
  • 사용 예시: 제스처 애니메이션을 종료하거나 상태를 정리할 때.

로 정리할 수 있다.

Override해서 log를 찍어보자

// logger_navigator_observer.dart
import 'package:flutter/material.dart';
import 'dart:developer';

class LoggerNavigatorObserver extends NavigatorObserver {
  
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    print(route);
    _logNavigation(route.settings.name, 'push');
  }

  
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    _logNavigation(route.settings.name, 'pop');
  }

  
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
    if (newRoute != null) {
      _logNavigation(newRoute.settings.name, 'replace');
    }
  }

  void _logNavigation(String? routeName, String action) {
    if (routeName != null) {
      log("Screen $action: $routeName", name: 'Navigation');
    }
  }
}

필요하다고 생각하는 부분에 해당 로그를 찍을 수 있게 파일을 하나 만들고,

// main.dart
 
  Widget build(BuildContext context, WidgetRef ref) {
    final userState = ref.watch(userViewModelProvider);

    return MaterialApp(
        navigatorObservers: [
          LoggerNavigatorObserver(),
        ],
        routes: {
          '/chat_create': (context) => ChatCreate(),
          '/chat_page': (context) => ChatPage(),
          '/chat_submit': (context) => ChatSubmitPage(),
          '/login': (context) => LoginPage(),
          '/map': (context) => MapPage(),
          '/resigter': (context) => RegisterPage()
        },
        title: 'Match-up',
        theme: ThemeData(
          fontFamily: 'Pretendard',
        ),
        home: _getHome(userState));
  }
  

MaterialAppnavigatorObservers 파라미터에 넣어주면 된다.

결과

신나서 왔다갔다 해보니 이렇게 찍힌다. 이걸 이쁘게 찍을수 있는 프로젝트를 해보자

0개의 댓글