본문 바로가기
flutter

플러터 - Navigation

by 들풀민들레 2023. 3. 13.

 

본 글은 [Do it! 깡샘의 플러터&다트 프로그래밍] 의 내용을 발췌한 것입니다.

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

라우트 이해하기


플러터에서는 화면과 관련된 모든 것이 위젯입니다. 화면을 구성하는 문자열, 이미지도 위젯이며 화면 전체도 위젯입니다. 이제껏 살펴본 것처럼 위젯은 계층 구조로 구성됩니다. 그런데 대부분의 앱은 여러 화면으로 구성됩니다. 예를 들어 쇼핑 앱이라면 다음 그림처럼 로그인, 상품 목록, 장바구니 화면 등으로 구성됩니다. 이런 화면도 하나의 위젯으로 만들어 계층 구조로 구성해야 합니다.

이 그림처럼 화면이 3개인 앱을 만든다고 가정해 보겠습니다. 각각의 화면을 MyLoginScreen, MyCatalogScreen, MyCartScreen이라는 위젯 클래스로 만들 수 있습니다. 그리고 이 위젯을 다시 MyApp이라는 루트 위젯에 추가해서 다음처럼 계층으로 구성할 수 있습니다.

그런데 MyApp은 한 번에 한 화면씩 나오게 해야 합니다. 즉, 화면을 구성하는 여러 위젯을 준비하고 한 순간에 하나의 위젯만 보이게 화면을 전환해 줘야 합니다. 이처럼 화면 전환을 제공하려면 Route와 Navigator를 사용합니다.
Route는 화면을 지칭하는 객체입니다. 화면은 위젯 클래스로 만들어야 하지만, 그 위젯 클래스를 포함해 화면을 구성하는 다양한 정보를 Route 객체에 설정하여 화면을 표현합니다. 그리고 Navigator 위젯은 Route 객체로 화면을 전환해 줍니다. Navigator는 화면이 전환되면서 생성된 Route들을 스택 구조로 관리하는데, 화면 전환뿐만 아니라 이전 화면으로 되돌아가거나 화면 전환 애니메이션 효과 등 다양한 기법을 제공합니다.
예를 들어 앱의 화면을 다음처럼 만들었다고 가정해 보겠습니다.

void main() {
	runApp(MyApp());
}
class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
    	return MaterialApp(
    		home: OneScreen(),
    	);
    }
}
class OneScreen extends StatelessWidget {
	... (생략) ...
}
class TwoScreen extends StatelessWidget {
	... (생략) ...
}

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

 

runApp() 함수로 출력할 앱의 루트 위젯인 MyApp에서 OneScreen 위젯을 home으로 지정했으므로 처음엔 OneScreen 위젯이 출력됩니다.

OneScreen 화면에서 버튼을 누를 때 TwoScreen으로 화면을 전환하고 싶다면 Navigator.push() 함수를 호출합니다.

ElevatedButton(
    child: Text('Go Two Screen'),
    onPressed: () {
        Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => TwoScreen()),
        );
    },
),

Navigator.push() 함수의 두 번째 매개변수가 전환할 화면을 지칭하는 라우트 객체입니다. 라우트 객체는 추상형으로 직접 구현하거나 머티리얼 디자인에서 제공하는 애니메이션 기능 등이 포함된 MaterialPageRoute를 이용합니다. 라우트 객체의 builder 함수에서 전환할 화면의 위젯 객체를 생성해 반환하면 됩니다.
Navigator.push() 함수는 두 번째 매개변수로 지정한 라우트 객체를 Navigator가 관리하는 스택에 추가해 줍니다. 화면에는 Navigator 스택에서 맨 위에 있는 라우트의 위젯이 출력되므로 TwoScreen 화면이 출력됩니다.

또한 TwoScreen 화면에서 이전 화면으로 되돌아가자면 Navigator.pop() 함수를 이용합니다. 오른쪽은 TwoScreen의 버튼을 누를 때 이전 화면으로 되돌아가는 코드입니다.

ElevatedButton(
    onPressed: () {
   	 	Navigator.pop(context);
    },
    child: Text('Go back!'),
),

이처럼 화면을 구성하는 위젯을 여러 개 만든 후 원하는 순간에 Navigator.push() 함수로 화면을 전환하고, Navigator.pop() 함수를 이용해 이전 화면으로 쉽게 되돌아갈 수 있습니다.


라우트 이름으로 화면 전환하기


그런데 Navigator.push() 함수로 화면을 전환하는 방법은 화면이 많아지고 화면과 화면이 복잡하게 연결되는 구조에서는 비효율적일 수 있습니다. 이때 MaterialApp의 routes 속성을 이용하면 앱의 화면을 등록하고 이 정보를 바탕으로 화면을 전환할 수 있습니다.
다음 코드는 routes 속성에 라우트 이름과 화면 위젯을 등록한 예입니다. 이렇게 하면 화면 전환이 필요한 곳에서 라우트 이름으로 쉽게 이용할 수 있습니다.

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            initialRoute: '/',
            routes: {
                '/': (context) => OneScreen(),
                '/two': (context) => TwoScreen(),
                '/three': (context) => ThreeScreen()
            },
        );
    }
}

이 코드에서 MaterialApp의 routes 속성에 등록한 라우트 이름 '/', '/two', '/three'는 개발자가 임의로 지정하는 문자열입니다. 또한 initialRoute 속성에는 처음 출력할 라우트 이름을 설정합니다. 예에서는 OneScreen이 첫 화면으로 출력됩니다.
routes에 등록한 이름으로 화면을 전환하려면 Navigator의 pushNamed() 함수를 이용합니다. 다음은 OneScreen 화면에서 TwoScreen 화면으로 전환하는 코드입니다.

ElevatedButton(
    child: Text('Go Two Screen'),
    onPressed: () {
    	Navigator.pushNamed(context, '/two');
    },
),

Navigator.pushNamed() 함수의 두 번째 매개변수에 전환할 라우트 이름만 명시하면 해당 라우트에 등록된 화면으로 전환됩니다. 결국 라우트 이름을 이용하면 화면 전환이 필요한 곳에서 전환할 위젯 클래스에 종속적인 코드를 작성하지 않아도 되며, 단지 문자열로 이름만 명시하면 되므로 편리합니다. 또한 MaterialApp의 routes 속성에 앱의 화면을 일관되게 등록하므로 전체 화면 구조를 한눈에 파악하기도 좋습니다.

 

 

 

책의 모든 내용을 저자 직강으로 진행한 강의는 ssamz.com 에서 들으실 수 있습니다.

 

 

'flutter' 카테고리의 다른 글

플러터 - Future, FutureBuilder  (0) 2023.03.13
플러터 - dio  (0) 2023.03.13
플러터 - Scaffold  (0) 2023.03.13
플러터 - ListView  (0) 2023.03.13
플러터 - TextField  (0) 2023.03.13