[Flutter]Navigator

한상욱·2023년 4월 25일
0

Flutter 위젯

목록 보기
21/22
post-thumbnail

들어가며

Flutter는 앱 안에서 새로운 화면으로 이동하려면 Navigator를 사용합니다. 이번 포스팅에서는 Navigator에 대해서 알아보도록 하겠습니다.

환경 구성

페이지 이동 구현을 위한 2개의 페이지가 필요합니다. 첫번째 페이지는 First, 두번째 페이지는 Second라고 하겠습니다.

first.dart

import 'package:flutter/material.dart';

class First extends StatelessWidget {
  const First({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Page'),
      ),
    );
  }
}

Second.dart

import 'package:flutter/material.dart';

class Second extends StatelessWidget {
  const Second({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
    );
  }
}

First에서 Second로 페이지를 각각 Navigator를 이용해서 이동시키도록 하겠습니다.

Flutter 프로젝트에서 화면 이동을 구현하려면 Navigator를 사용해야 합니다. 물론, Navigator를 이용하지 않고 화면 전환은 항상 가능합니다. BottomNavigationBar처럼 말이죠. 하지만, Navigator는 페이지가 이동하는 애니메이션까지 함께 제공되요. 부드러운 UX를 구현하기 위해서 사용하면 매우 좋겠죠? 물론, 직접 Navigator를 만들수도 있습니다. 자, 이제 본격적으로 화면이동을 해볼까요?

화면 이동은 보통 버튼을 누를때 많이 사용합니다. 그래서, 저희도 화면 이동이 가능한 버튼을 First.dart 파일에 만들어 두겠습니다.

...
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton.icon(
              onPressed: () {},
              icon: Icon(Icons.arrow_forward),
              label: Text('Push'),
            )
          ],
        ),
      ),
...

왜 Column과 Center가 있는지 궁금하다면, 그냥 여러개 만들고 가운데로 정렬하고 싶어서 사용한거지 의미는 딱히 없습니다. 중요한건 버튼을 ElevatedButton위젯의 icon을 이용했다는 점이죠. 이것도 역시 아이콘과 텍스트를 함께 넣으려고 사용했습니다.

Push 방식

가장 기본적으로 사용하는 방식은 Push 방식입니다. 일단 Push 방식으로 페이지 이동을 구현해놓고 Flutter의 페이지 이동 관리에 대해서 알아봅시다. Navigator는 아래와 같이 사용할 수 있어요.

Navigator.of(context).push(
						MaterialPageRoute(
                        	builder: (context) => Second()));

이야 조금 길지만, 이렇게 사용해야 합니다. push 방식에서 사용하는 MaterialPageRoute는 Material UI에 대한 페이지 이동 방식입니다. 쉽게 얘기해서 Android 폰은 새로운 화면이 가운데에서 확 나오는 듯한 느낌으로 이동을 하잖아요? 그런 느낌을 줄 수 있어요. 근데, 이것도 옛날버전 이야기고 지금 버전에서는 OS에 알맞은 페이지 이동을 구현시켜줍니다. 원래는 CupertinoPageRoute라는 것을 사용해야 했어요. 이젠 필요가 없을듯 합니다.

자, 잡담은 이제 집어치우고, Flutter는 페이지 이동을 스택방식으로 관리합니다. 스택은 먼저 들어오면 제일 나중에 나가잖아요. 그런것처럼 페이지가 이동할때마다 스택이라는 것으로 쌓입니다. 3번 이동하면 3번 뒤로 갈 수 있는거죠.

그 중에서 push방식은 가장 기본적인 방식이에요. 다음 페이지로 이동하면서 현재 페이지에 대한 스택이 가장 최근 스택으로 남게 되는겁니다. 이제 뒤로 이동하기를 누르면 다시 First로 갈 수 있겠죠? 제가 말하는 뒤로 이동하기 버튼은 Android에서 지원하는 3button 중 뒤로가기 버튼을 이용한 것을 얘기하는겁니다.

이동하기 전이동한 후

사실, 저는 예제 앱을 메인화면에서 여러개의 예제 페이지로 분할시키고, 버튼을 눌러서 에제를 작성합니다. 상단 앱바에 arrow_back 아이콘이 항상 보이거든요. push방식으로 페이지를 이동하면 Flutter가 자동으로 arrow_back 버튼을 랜더링해줍니다.

PushAndRemoveUntil

이 방식은 기존의 push방식에서 생성하는 페이지 스택을 모조리 지우는 옵션을 가지고 있습니다.

Navigator.of(context).pushAndRemoveUntil(
                    MaterialPageRoute(builder: (context) => Second()),
                    (route) => false);

이번에는 push방식과 다르게 2개의 positional 아규먼트가 전달된것이 보이죠? 첫번째로 전달하는 아규먼트는 Route방식입니다. 그리고 두번째로 전달하는 아규먼트는 항상 저렇게 고정하셔야 해요. 안그러면 이거 쓰는 의미가 없습니다.

이 방식으로 페이지를 이동하게 되면 현재까지 쌓인 페이지 스택이 모조리 삭제됩니다. 어떨 때 사용하면 될까요? 로그인화면에서 인증이 완료되면 사용하면 딱이죠? 스택이 모조리 사라졌다는 의미는 뒤로가기 버튼 한번 더 눌렀을 때, 앱이 꺼지게 된단 소리입니다.

이동하기 전이동한 후

이번에도 이동을 완료해도 arrow_back이 없네요. 어짜피 뒤로 갈 페이지도 없습니다.

PushReplacement

이 방식은 Push 방식과 동일합니다. 근데, 기존에 이동하기 전 페이지가 남겨야할 스택을 없애버립니다. 그래서 Second에서 뒤로가기 버튼을 누르면 앱이 또 꺼지겠죠? 페이지가 없을테니까요. 사용법은 push와 이름만 달라요.

Navigator.of(context).pushReplacement(
                    MaterialPageRoute(builder: (context) => Second()));

pop

pop은 보통 맨 뒤에 것을 지운다라는 의미죠? 그래서 pop방식은 뒤로가기와 같습니다.

Navigator.of(context).pop();

이 친구는 굉장히 쓰기 간편하죠? 저게 끝입니다. 이렇게 가장 많이 사용하는 페이지 이동방식 4가지에 대해서 알아보았습니다.

Named Route

자 지금까지 다뤘던 페이지 이동방식은 모두 Class를 반환하는 방식이었습니다. 근데, Flutter에는 Named Route라는게 있습니다. 이 방식은 내가 지정한 Named Route로 페이지를 이동시킨다는 의미에요. 이 방식을 사용하기 위해서는 사전 작업이 필요합니다.

...
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: App(),
      routes: {
        '/Second': (context) => Second(),
      },
    );
    ...

이 방식을 사용하기 위해서 Named Route를 등록시켜야합니다. MaterialApp 안에는 route를 지정할 수 있는 프로퍼티가 존재해요. 그 안에 Map 자료로 설정할 수 있습니다. 저렇게 지정하면 이제 Named Route를 통한 페이지 이동이 가능합니다.

Navigator.of(context).pushNamed('/Second');

위 코드는 Named Route를 이용한 push방식입니다. 다른 방식들도 Named Route를 지정하고 있고, 지금 보면 코드가 굉장히 간결해졌습니다. 게다가 Named Route를 지정하면, 라우트 관리가 굉장히 수월해요. 아주 좋은 기능이죠?

이번 포스팅은 여기까지만 하도록 하겠습니다!

profile
자기주도적, 지속 성장하는 모바일앱 개발자가 되기 위해

0개의 댓글