Route란 무엇인가, Flutter에서 라우트 유형 및 생성

저자: IT Sectr 게시일: 2026-07-02 읽는 시간: 8 분

Route는 Navigator의 탐색 기록에서 개별 화면이나 페이지를 나타내는 Flutter의 추상 클래스입니다. Route의 구체적인 구현인 MaterialPageRoute, CupertinoPageRoute 및 PlatformRoute는 화면이 표시되는 방식과 전환 중 사용할 애니메이션을 결정합니다. 일반 위젯과 달리 Route는 didPush, didPop, didReplace 및 didChangeNext 메서드가 있는 자체 수명 주기를 가지고 있습니다. Flutter API Reference (2026)에 따르면 각 Route는 ModalBarrier를 관리하고 플랫폼별 기능(iOS의 스와이프 뒤로)을 고려하며 화면 간 상태 격리를 보장합니다.

핵심 사항

  • Route — 자체 수명 주기(didPush, didPop, didReplace, didChangeNext)를 가진 Flutter의 추상 화면 클래스
  • MaterialPageRoute — Android 및 데스크탑용 Material 애니메이션(아래에서 슬라이드)이 있는 표준 Route 구현
  • CupertinoPageRoute — iPhone 및 iPad용 iOS 애니메이션(오른쪽에서 슬라이드 + 제스처 스와이프 뒤로)이 있는 Route 구현
  • 수명 주기 — Route는 전환, 활성, 비활성 및 폐기 단계를 거칩니다
  • 데이터 전송 — Route는 생성자를 통해 인수를 받고 완료 시 Future를 통해 결과를 반환합니다

Flutter에서 Route란

Route는 Flutter 탐색 시스템의 기초입니다. 사용자가 애플리케이션에서 보는 각 화면은 Navigator 스택에 있는 Route 객체로 표현됩니다. Route는 제어 코드에서 화면을 추상화합니다. Navigator가 Route를 추가하고 제거하는 반면, Route 내부에는 사용자가 보는 인터페이스가 있습니다. 이 아키텍처는 탐색과 표시 간의 책임을 분리합니다.

단순한 위젯 교체와 달리 Route는 일반 위젯에서 사용할 수 없는 서비스를 제공합니다: ModalBarrier(대화상자가 열릴 때 배경 어두워짐), 입장 및 퇴장 애니메이션 제어, Android의 하드웨어 뒤로 가기 버튼 처리, 화면 간 부드러운 전환을 위한 Hero 애니메이션 통합.

Flutter Cookbook (2026)에 따르면 Route는 Hero 애니메이션의 핵심 요소입니다. 한 Route의 Hero 위젯은 다음 Route의 Hero 위젯으로의 전환을 자동으로 애니메이션하여 “날아가는” 요소 효과를 만듭니다. 이는 Route가 애니메이션 중에 두 화면을 모두 Overlay에 유지하기 때문에 가능합니다.

탐색의 구성 요소로서의 Route

Route는 단순한 모바일 애플리케이션(Navigator 1.0을 통해)과 딥 링크가 있는 복잡한 시나리오(Navigator 2.0) 모두의 기초입니다. Navigator 2.0에서 Route는 RouterDelegate가 라우트 구성에서 변환하는 Page를 나타냅니다. 따라서 선택한 접근 방식이나 패키지에 관계없이 Flutter 탐색 시스템으로 작업하려면 Route를 이해하는 것이 필수적입니다.

Route 유형: MaterialPageRoute 및 CupertinoPageRoute

Flutter는 각각 특정 플랫폼에 동작을 조정하는 여러 내장 Route 구현을 제공합니다. 올바른 Route 유형을 선택하는 것은 사용자 경험에 영향을 미칩니다. Android의 Material 애니메이션과 iOS의 Cupertino 애니메이션은 “네이티브” 애플리케이션의 느낌을 만듭니다.

Route 유형애니메이션플랫폼특징
MaterialPageRoute아래에서 위로 슬라이드Android, 데스크탑전환 시 그림자, 자동 SafeArea 처리
CupertinoPageRoute오른쪽에서 왼쪽으로 슬라이드iOS, iPadOS제스처 스와이프 뒤로, 전환 중 투명 배경
PlatformRoute자동 선택모든 플랫폼TargetPlatform에 따라 유형 선택
PageRouteBuilder사용자 정의모든 플랫폼AnimationController를 통한 애니메이션 완전 제어

MaterialPageRoute: Android 표준

MaterialPageRoute는 가장 많이 사용되는 Route 구현입니다. 새 화면이 아래에서 위로 점진적으로 나타나며 애니메이션됩니다. 종료 시 화면은 위에서 아래로 애니메이션되어 원래 위치로 돌아갑니다. 도구 모음(AppBar)과 화면 본문은 별도로 애니메이션되어 계층 구조 효과를 만듭니다.

CupertinoPageRoute: iOS 탐색 스타일

CupertinoPageRoute는 iOS의 UINavigationController를 모방합니다. 새 화면은 오른쪽에서 들어와 이전 화면을 덮습니다. 주요 특징은 CupertinoBackGestureDetector를 통해 구현된 대화형 스와이프 뒤로 제스처 지원입니다. 이 제스처는 애니메이션 중에도 처리되어 iPhone 사용자에게 친숙한 자연스러운 동작을 제공합니다.

Route 수명 주기: 생성부터 폐기까지

Route는 일반 StatefulWidget의 수명 주기와 다른 자체 수명 주기를 가지고 있습니다. 이 주기를 이해하는 것은 올바른 데이터 초기화, 스트림 구독 및 화면 종료 시 리소스 해제에 필요합니다.

Route 수명 주기 단계

Route 수명 주기는 네 가지 주요 단계로 구성됩니다. 전환 — Route가 생성되고 입장 시 애니메이션됩니다(didPush 호출). 활성 — Route가 완전히 표시되고 사용자와 상호 작용합니다. 비활성 — 다른 Route가 현재 Route를 덮습니다(대화상자, 바텀 시트) but Route는 스택에 남아 있습니다. 폐기 — Route가 스택에서 제거되고 파괴되며 didPop 및 dispose가 호출됩니다.

Route 수명 주기 메서드는 사용자 정의 구현에서 재정의될 수 있습니다. 예를 들어 didPop은 Route가 스택에서 제거될 때 호출됩니다 — 여기서 초안 데이터를 저장할 수 있습니다. didChangeNext는 스택의 다음 Route가 변경될 때 호출됩니다 — 탐색 기록이 변경될 때 UI를 업데이트하는 데 유용합니다.

Flutter API Route.didPop (2026)에 따르면 Route의 수명 주기를 Route 내부 State의 수명 주기와 혼동하지 않는 것이 중요합니다. Route 내부의 StatefulWidget에는 각각 전환 및 폐기 단계에서 호출되는 자체 initState 및 dispose가 있습니다. Route는 내부 State보다 오래 살며 Route는 위젯이 다른 Route에 의해 일시적으로 숨겨져 있어도 Overlay에 남아 있습니다.

Route를 통한 화면 간 데이터 전달

Route는 입력(생성 시)과 출력(완료 시) 모두에서 데이터를 전달하는 메커니즘을 제공합니다. Route를 통한 적절한 데이터 전달은 전역 변수와 InheritedWidget을 필요 없게 만들어 탐색을 타입 안전하고 예측 가능하게 만듭니다.

새 화면에 데이터를 전달하려면 수신 위젯의 생성자 또는 Navigator.pushNamed의 arguments 매개변수를 사용하세요. Route 내부에서는 Route 객체에 저장된 RouteSettings.arguments를 통해 데이터에 접근할 수 있습니다. 이 접근 방식은 MaterialPageRoute, CupertinoPageRoute 및 사용자 정의 구현을 포함한 모든 Route 유형에서 작동합니다.

데이터를 반환하려면 Navigator.pop(context, result)의 두 번째 인수를 사용하세요. Navigator.push는 Future를 반환하며, pop에 전달된 값으로 완료됩니다. pop이 인수 없이 호출되면 Future는 null로 완료됩니다. 이 메커니즘은 Android의 startActivityForResult 및 iOS의 completion handler와 유사하지만 Dart Futures를 통해 구현됩니다.

Route 생성자를 통한 데이터 전달

MaterialPageRoute로 Navigator.push를 직접 호출할 때 데이터는 대상 화면의 생성자를 통해 전달됩니다. MethodChannel은 사용되지 않습니다 — 이것은 순수한 Dart 상호 작용입니다. 이 접근 방식은 복잡한 객체의 타입 안전 전달에 선호됩니다.

사용자 정의 Route 생성 예제

자체 애니메이션과 데이터 전달이 있는 사용자 정의 Route를 만드는 예제를 살펴보겠습니다. PageRouteBuilder를 사용하면 애니메이션 곡선과 지속 시간을 완전히 제어하여 입장 및 퇴장 애니메이션을 정의할 수 있습니다.

dart
// 슬라이드 애니메이션이 있는 사용자 정의 Route
Navigator.push(context, PageRouteBuilder(
  pageBuilder: (context, animation, secondaryAnimation) {
    return DetailPage(productId: '42');
  },
  transitionsBuilder: (context, animation, secondaryAnimation, child) {
    const begin = Offset(0.0, 0.3);
    const end = Offset.zero;
    final tween = Tween(begin: begin, end: end);
    final offsetAnimation = animation.drive(tween);
    return SlideTransition(position: offsetAnimation, child: child);
  },
  transitionDuration: const Duration(milliseconds: 400),
));

// 화면에서 데이터 반환
ElevatedButton(
  onPressed: () => Navigator.of(context).pop({'selected': true, 'id': '42'}),
  child: const Text('선택'),
);

// 호출 화면에서 결과 가져오기
final result = await Navigator.push(context, MaterialPageRoute(
  builder: (context) => const SelectionPage(),
));
if (result != null) {
  print('선택됨: ${result['selected']}');
}

예제에서 PageRouteBuilder는 투명도가 있는 아래에서 사용자 정의 슬라이드 애니메이션을 정의합니다. transitionDuration은 애니메이션 속도를 설정합니다. 코드는 결과 전달도 보여줍니다: 세부 화면은 사용자 선택이 있는 Map을 반환하고 호출 화면은 push의 Future를 통해 이 데이터를 받습니다. Route는 완전한 격리를 보장합니다: 세부 화면의 초안은 목록 상태에 영향을 미치지 않습니다.

자주 묻는 질문

Flutter에서 Route와 Widget의 차이점은 무엇인가요?

Route는 탐색 수준에서 화면을 관리하는 객체입니다: 애니메이션, ModalBarrier 및 수명 주기를 저장합니다. Widget은 인터페이스의 일부에 대한 설명입니다. Route는 내부에 Widget을 포함하지만 일반 위젯에서 사용할 수 없는 서비스(Overlay 레이어, Hero 애니메이션)도 제공합니다. 하나의 Route는 모든 깊이의 복잡한 위젯 계층 구조를 포함할 수 있습니다.

사용자 정의 애니메이션으로 Route를 만들려면 어떻게 하나요?

pageBuilder(화면 구성) 및 transitionsBuilder(애니메이션 정의) 매개변수와 함께 PageRouteBuilder를 사용하세요. transitionsBuilder에서는 병렬 애니메이션을 위해 animation(0.0–1.0) 및 secondaryAnimation을 사용할 수 있습니다. 완전한 제어를 위해 Route의 하위 클래스를 만들고 buildPage, createAnimationController 및 buildTransitions를 재정의하여 저수준 AnimationController에 접근하세요.

Route 간에 복잡한 객체를 전달하려면 어떻게 하나요?

복잡한 객체를 전달하려면 Navigator.push를 직접 호출할 때 대상 화면의 생성자를 사용하거나 pushNamed와 함께 arguments 매개변수를 사용하세요. 객체가 직렬화 가능(Map, JSON 또는 사용자 정의 클래스)한지 확인하세요. Flutter에서 타입 안전 전달을 위해 freezed 또는 json_serializable 모델을 사용하여 RouteSettings를 통한 전달 시 올바른 역직렬화를 보장하세요.

Route가 dispose를 호출하지 않을 수 있는 이유는 무엇인가요?

Route가 Navigator 스택에 남아 있으면 Route.dispose가 호출되지 않습니다. 예를 들어 새 Route를 열 때 이전 Route는 비활성 상태가 되지만 파괴되지 않습니다 — 빠른 복귀를 위해 스택에 남아 있습니다. Dispose는 pop, pushReplacement 또는 pushAndRemoveUntil을 통해 Route가 스택에서 제거될 때만 호출됩니다. 리소스를 해제하려면 Route 자체의 dispose가 아닌 Route 내부 State의 dispose를 사용하세요.

현재 활성화된 Route를 확인하려면 어떻게 하나요?

BuildContext에서 현재 Route를 가져오려면 ModalRoute.of(context)를 사용하세요. ModalRoute.isActive 속성은 Route가 현재 표시되는 화면인지 보여줍니다. ModalRoute.isCurrent — Route가 스택의 최상위면 true입니다. 스택 변경을 관찰하려면 RouteAware 및 RouteObserver를 통해 Navigator 관찰자를 구독하여 활성 Route 변경에 대한 알림을 받으세요.

요약

  • Route — 수명 주기(didPush, didPop, didReplace, didChangeNext)와 ModalBarrier 및 Hero 애니메이션 지원이 있는 Flutter의 추상 화면 클래스
  • MaterialPageRoute — 아래에서 슬라이드 애니메이션, 그림자 및 자동 SafeArea가 있는 Android 구현
  • CupertinoPageRoute — 오른쪽에서 슬라이드 애니메이션 및 대화형 스와이프 뒤로 제스처가 있는 iOS 구현
  • PageRouteBuilder — transitionsBuilder 및 AnimationController를 통해 사용자 정의 애니메이션으로 Route를 생성하는 유틸리티
  • 데이터 전달 — 입력 시 Route 생성자(push) 또는 arguments(pushNamed)를 통해; 출력 시 Future와 함께 Navigator.pop(context, result)를 통해
  • 수명 주기 — 네 단계: 전환(didPush), 활성, 비활성(다른 Route로 덮임), 폐기(didPop + dispose)
  • 화면 격리 — 각 Route는 자체 BuildContext 및 상태를 가지며 누수를 방지하고 데이터 관리를 단순화합니다

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기