본문으로 바로가기
  1. Home
  2. Flutter/Widget
  3. Flutter Navigator(push, pop, replace) 문서

Flutter Navigator(push, pop, replace) 문서

· 댓글개 · Dev_Whale

Navigator는 화면을 이동하거나 닫거나 또는 화면을 대체할 때 사용하는 위젯입니다. 이 글에서는 Navigator의 메서드 종류와 각 메서드가 어떤 역할을 하는지 설명하는 글입니다.

Navigator 메서드 종류

push, pop, replace 세 종류가 있습니다.

  • push - 기존 화면 위에 불러올 화면을 불러옵니다.
  • pop - 현재 화면을 닫습니다.
  • replace - 현재 화면을 대체할 때 사용합니다.

Named가 붙어있는 메서드 사용하기 위한 사전 작업

MaterialApp 또는 CupertinoApp에서 routes에 원하는 화면을 사전에 지정해둬야 Named가 붙어있는 메서드를 사용할 수 있습니다.

Flutter에서 route는 무슨 의미일까요?
Flutter에서는 페이지나 화면을 Route라고 합니다. 그렇게 되면 routes는 페이지의 모음 정도로 생각하면 될 것 같습니다.
Android에서는 이러한 페이지/화면을 Activity라고 하고 iOS에서는 ViewController라고 합니다.
class MyApp extends StatelessWidget {
  final ButtonStyle style = ElevatedButton.styleFrom(minimumSize: Size(310, 35), textStyle: TextStyle(fontSize: 18));

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(elevatedButtonTheme: ElevatedButtonThemeData(style: style)),
      home: FirstPage(),
      routes: <String, WidgetBuilder>{
        '/screen1': (BuildContext context) => FirstPage(),
        '/screen2': (BuildContext context) => SecondPage(),
        '/screen3': (BuildContext context) => ThirdPage(),
        '/screen4': (BuildContext context) => FourPage(),
        '/blankPage': (BuildContext context) => BlankPage(),
        '/NumberCheckPage': (BuildContext context) => NumberCheckPage(),
      },
    );
  }
}

Push Method

push

push, pushNamed메서드를 실행하면 불러올 페이지가 현재 페이지 위에 쌓이게 됩니다. 스택 개념과 유사하다고 볼 수 있습니다.

ElevatedButton(
  onPressed: () {
    Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
  },
  child: Text('Screen2 Push'),
)

pushNamed

ElevatedButton(
  onPressed: () {
    Navigator.pushNamed(context, '/screen2');
  },
  child: Text('Screen2 PushNamed'),
)

pushAndRemoveUntil

pushAndRemoveUntil, pushAndRemoveUntilNamed 메서드는 모든 페이지 제거 후 지정한 페이지를 push 합니다.

사용하는 경우

  1. 로그인을 정상적으로 완료한 후에 로그아웃을 하지 않는 이상 로그인 화면으로 이동할 경우가 없을 때
  2. 일회성으로만 사용되는 화면일 때
ElevatedButton(
  onPressed: () {
  // 모든페이지 제거 후 특정페이지로 이동
    Navigator.pushAndRemoveUntil(context, MaterialPageRoute(builder: (context) => FirstPage()), (route) => false);
  },
  child: Text('pushAndRemoveUntil Screen 1'),
)

pushAndRemoveUntilNamed

ElevatedButton(
  onPressed: () {
    Navigator.pushNamedAndRemoveUntil(context, '/screen1', (route) => false); (route) => false);
  },
  child: Text('pushAndRemoveUntil Screen 1'),
)

popAndPushNamed

현재 페이지를 pop후 지정한 페이지를 push 합니다

ElevatedButton(
  onPressed: (){
    Navigator.popAndPushNamed(context, '/screen1');
  },
  child: Text('popAndPushNamed Screen1'),
)

Pop Method

pop

현재 페이지를 닫습니다. 닫을 페이지가 없다면 블랙 스크린이 발생합니다. 제가 직접 실험해봤으니 건너뛰셔도 됩니다.

ElevatedButton(
  onPressed: () {
    Navigator.of(context).pop();
  },
  child: Text('Pop'),
)

canPop

Pop이 가능한지 여부를 묻고 true, false를 반환

ElevatedButton(
  onPressed: () {
    if (Navigator.canPop(context)) {
      Navigator.of(context).pop();
    } else {
      print('불가');
    }
  },
  child: Text('canPop'),
)

maybePop

뒷 페이지가 없는 상태에서 Pop을 하게 된다면 blackScreen 이 뜹니다. 이것을 방지할 수 있는 메서드 이지만 조사해보니 아직 모르는 부분이 존재하는것 같습니다. 이것과 연관된 onWillPopScope에 대해 작성할 때 수정하도록 하겠습니다.

ElevatedButton(
  onPressed: () {
    Navigator.maybePop(context, moo());
  },
  child: Text('maybePop'),
)

popAndPushNamed

현재 페이지를 pop후 지정한 페이지를 push 합니다.

ElevatedButton(
  onPressed: () {
    Navigator.popAndPushNamed(context, '/screen1');
  },
  child: Text('popAndPushNamed Screen1'),
)

Replace Method

pushReplacement

현재 페이지를 한번 pop후 지정한 페이지를 Push 합니다.
예를 들어 1번 스크린, 2번 스크린, 3번 스크린이 구현되어 있다고 가정을 합니다.
초기화면 1번 스크린에서 2번 스크린을 push 합니다. 그러면 1번 스크린 위에 2번 스크린이 존재하게 됩니다.

여기서 2번 스크린에서 3번 스크린으로 pushReplacement를 하게 된다면 routes가 어떻게 될까요?

1. 3번 스크린만 존재한다.
2. 1번 스크린, 2번 스크린, 3번 스크린으로 존재한다.
3. 1번 스크린, 3번 스크린 순으로 존재한다.

정답을 아시는 분은 댓글을 남겨주시고 모르시는 분은 간단하게 구현해서 직접 확인해보시길 바랍니다.

pushReplacementNamed

현재 스크린을 지정한 스크린으로 대체합니다. 이때 까지 설명한 메서드 중에서 결과는 같지만
과정이 다른 메서드가 존재합니다.
무엇일까요? 3... 2.. 1. popAndPushNamed 메서드 입니다.
두 메서드의 결과는 같습니다. popAndPushNamed 메서드는 현재 스크린을 닫고 지정한 스크린을 push 합니다.
하지만 pushRelacementNamed 메서드는 현재 페이지가 대체 됩니다.
직접 눈으로 확인하기 위해서는 slow motion 을 켜두고 확인하시면 됩니다. 처음에는 차이가 잘 안보일순 있지만
몇번 반복하다보면 두 메서드의 애니메이션 차이가 보이실 겁니다.

ElevatedButton(
  onPressed: () {
    Navigator.pushReplacementNamed(context, '/screen2');
  },
  child: Text('pushReplacementNamed Screen2'),
),

Source Code

SeongWoo-97/blog_upload_project

Contribute to SeongWoo-97/blog_upload_project development by creating an account on GitHub.

github.com

Reference

Routes and Navigator in Flutter - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

최근 글
Dev_Whale의 Flutter 블로그
추천하는 글
Dev_Whale의 Flutter 블로그
💬 댓글 개
이모티콘창 닫기
울음
안녕
감사해요
당황
피폐

이모티콘을 클릭하면 댓글창에 입력됩니다.