Dev./Flutter

[Flutter / 플러터] 네비게이터와 페이지 전환

Wonder Park 2026. 1. 12. 22:19
728x90

Navigator와 페이지 전환: 앱의 흐름을 설계하는 법

최근 바이브코딩 프로젝트를 진행하면서 느끼는 점은, 앱의 완성도는 결국 '매끄러운 사용자 경험'에서 나온다는 것입니다. 사용자가 버튼을 눌렀을 때 자연스럽게 상세 페이지로 이동하고, 다시 원래 자리로 돌아오는 기능은 앱의 가장 기본이자 핵심이죠. 오늘은 플러터에서 화면을 관리하는 거대한 관제탑, Navigator의 원리와 실전 사용법을 상세히 알아보겠습니다.


1. Navigator의 원리: Stack(스택) 구조

플러터의 화면 관리는 '종이 쌓기(Stack)'와 똑같습니다. 새로운 화면이 나타날 때 기존 화면을 지우는 것이 아니라, 그 위에 새로운 화면이라는 종이를 한 장 더 얹는 방식입니다.

  • 📥 Push (밀어 넣기): 새로운 페이지를 스택의 가장 위에 올립니다. (화면 이동)
  • 📤 Pop (꺼내기): 맨 위에 있는 종이를 치워 바로 아래에 있던 페이지를 보여줍니다. (뒤로 가기)

이러한 구조 덕분에 사용자가 '뒤로 가기'를 눌렀을 때 이전 화면의 상태(스크롤 위치 등)가 그대로 유지될 수 있는 것입니다.

2. 핵심 함수 상세 분석

① Navigator.push()

새로운 화면을 스택에 추가합니다. 이때 Route(경로)라는 개념이 필요합니다.

  • MaterialPageRoute: 플러터가 제공하는 기본 경로 생성기입니다. 안드로이드는 아래에서 위로, iOS는 옆에서 밀려오는 플랫폼별 특유의 애니메이션을 자동으로 적용해 줍니다.
  • builder: 이동할 새 페이지 위젯을 반환하는 함수를 작성합니다.

② Navigator.pop()

현재 화면을 닫고 이전 화면으로 돌아갑니다. 물리적인 뒤로 가기 버튼뿐만 아니라, 앱 내 '닫기' 버튼 등을 직접 구현할 때 사용합니다.

3. 여기서 다시 만나는 BuildContext

이전에 공부한 내용 중 BuildContext가 위젯의 '신분증'이자 '주소'라고 배웠습니다. 네비게이터를 쓸 때 왜 context를 인자로 넘겨줄까요?

Navigator 위젯은 보통 위젯 트리의 최상단에 살고 있습니다. 현재 위젯이 자신의 위치 정보(context)를 알려줘야 네비게이터가 "아, 너 지금 여기 있구나! 그럼 네 위에 새로운 화면을 쌓아줄게"라고 정확히 판단할 수 있기 때문입니다.

4. 실전 코드로 익히기

바이브코딩에서 활용할 수 있는 가장 기본적인 화면 전환 예제입니다.

// 1번 화면: 메인 페이지
class FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('메인')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // 상세 페이지로 이동 (Push)
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const SecondPage()),
            );
          },
          child: const Text('상세 보기'),
        ),
      ),
    );
  }
}

// 2번 화면: 상세 페이지
class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('상세 페이지')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => Navigator.pop(context), // 현재 화면 닫기 (Pop)
          child: const Text('닫기'),
        ),
      ),
    );
  }
}
        
⚠️ 흔한 실수: Pop할 화면이 없을 때
스택의 가장 마지막 페이지(홈 화면)에서 Navigator.pop(context)를 호출하면 앱이 꺼지거나 검은 화면이 나올 수 있습니다. Navigator.canPop(context)로 돌아갈 페이지가 있는지 먼저 확인하는 습관을 들이면 더욱 견고한 앱을 만들 수 있습니다.

💡 퀴즈 (Check-point)

Q. 새로운 화면으로 이동하여 스택에 '종이를 쌓을 때' 사용하는 함수는 무엇일까요?

(정답: Navigator.push()입니다! 반대로 현재 화면을 치울 때는 pop을 사용합니다.)

728x90