[GetX] 라우트 관리

2022-01-24 hit count image

Flutter에서 GetX를 사용하여 라우트 관리를 하는 방법에 대해서 알아봅시다.

개요

이번 블로그 포스트에서는 GetX를 사용하여 라우트(Route) 관리를 하는 방법에 대해서 알아보도록 하겠습니다. 이 블로그 포스트에서 소개하는 소스 코드는 아래에 링크에서 확인할 수 있습니다.

블로그 시리즈

이 블로그 포스트는 Flutter에서 GetX를 사용하는 방법에 관해 시리즈로 제작되었습니다. GetX의 다른 사용법을 알고 싶으시다면, 다음 링크를 참고하시기 바랍니다.

GetX 설치

Flutter에서 GetX의 사용법을 확인하기 위해 다음 명령어를 사용하여 Flutter의 새로운 프로젝트를 생성합니다.

flutter create route_management

그런 다음 명령어를 실행하여 GetX 패키지를 설치합니다.

flutter pub add get

이제 이렇게 설치한 GetX를 사용하여 라우트 관리를 하는 방법에 대해서 알아보도록 하겠습니다.

라우트 관리

Flutter에서 GetX 기능을 사용하기 위해서는 MaterialApp 대신 GetMaterialApp을 사용해야 합니다. 이를 확인하기 위해서 lib/main.dart를 다음과 같이 수정합니다.

...
@override
Widget build(BuildContext context) {
  return GetMaterialApp(
    title: 'Flutter Demo',
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: const MyHomePage(),
  );
}
...

그런 다음 첫 화면에 표시되는 MyHomePage 위젯을 다음과 같이 수정합니다.

...
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          child: const Text('Next Screen'),
          onPressed: () => Get.to(const Second()),
        ),
      ),
    );
  }
}
...

MyHomePage 위젯은 화면에 단순히 TextButton 위젯을 가운데에 표시하고, 해당 버튼을 누르면 Second 위젯으로 이동하도록 합니다.

Second 위젯으로 이동할 때, 다음과 같이 GetX의 Get.to를 사용하여 화면을 이동하도록 하였습니다.

Get.to(const Second())

이제 이동할 화면인 Second 위젯을 생성하기 위해 lib/second.dart 파일을 생성하고 다음과 같이 수정합니다.

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class Second extends StatelessWidget {
  const Second({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          onPressed: () => Get.back(),
          child: const Text('Go back'),
        ),
      ),
    );
  }
}

Second 위젯도 단순히 가운데에 TextButton 위젯을 표시하고, 해당 버튼을 누르면 이전 화면으로 이동하도록 하였습니다.

이전 화면으로 이동할 때에는 GetX의 Get.back 함수를 사용하였습니다.

Get.back()

GetX에서는 이와같이 Get.to와 위젯 클래스를 직접 사용하여 단순하게 화면 이동을 구현할 수 있습니다.

이름있는 라우트

하지만 이와 같이 위젯 클래스를 직접 사용하면, 화면 이동을 구현할 수 있지만, 라우트를 관리하기는 어렵습니다. 그래서 보통 GetX로 라우트를 관리할 때에는 이름있는 라우트(Named route)를 사용하게 됩니다.

이름있는 라우트를 확인하기 위해 lib/main.dart 파일을 다음과 같이 수정합니다.

...
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => const MyHomePage()),
        GetPage(name: '/second', page: () => const Second()),
      ],
    );
  }
}
...

이전 예제와는 다르게 GetPage를 통해 화면의 이름(name)과 해당 이름의 화면 위젯(page)을 설정합니다. 그리고 처음 앱을 실행했을 때, 표시될 첫 화면의 이름을 initialRoute 속성으로 설정합니다.

Flutter는 웹에서도 사용이 가능하기 때문에 화면의 이름은 URL 형식을 사용합니다.

이제 화면를 이동시키는 방법을 알아보겠습니다. 화면 이동 버튼을 가지고 있는 MyHomePage 위젯을 다음과 같이 수정합니다.

...
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          child: const Text('Next Screen'),
          onPressed: () => Get.toNamed('/second'),
        ),
      ),
    );
  }
}
...

이제 화면을 이동시킬 때에는 Get.toNamed과 미리 등록한 이름을 사용하여 화면을 이동시킬 수 있습니다.

Arguments 전달

GetX에서는 다음과 같이 화면을 이동할 때, 파라메터를 전달할 수 있습니다.

Get.toNamed("/first", arguments: "Hello");

이렇게 전달한 파라메터는 다음과 같이 접근하여 사용할 수 있습니다.

Get.arguments

또는 다음과 같이 URL 파라메터 형식으로 전달할 수도 있습니다.

getPages: [
  GetPage(name:"/", page: () => Home()),
  GetPage(name:"/first/:id", page: () => First()),
]
...
Get.toNamed("/first/1?name=hello");
...
Get.parameters["id"]
Get.parameters["name"]

이를 확인하기 위해 lib/main.dart 파일을 다음과 같이 수정합니다.

...
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextButton(
          child: const Text('Next Screen'),
          onPressed: () => Get.toNamed(
            '/second',
            arguments: {
              "greeting": "Hello",
              "name": "World",
            },
          ),
        ),
      ),
    );
  }
}
...

그리고 lib/second.dart 파일을 다음과 같이 수정합니다.

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('${Get.arguments['greeting']}, ${Get.arguments['name']}'),
            TextButton(
              onPressed: () => Get.back(),
              child: const Text('Go back'),
            ),
          ],
        ),
      ),
    );
  }
}
...

이를 실행하면 Hello, World가 화면에 표시되는 것을 알 수 있습니다. argumentsdynamic 타입이므로 모든 타입의 변수를 전달할 수 있습니다.

화면 이동 방법

화면을 이동시킬 때, 새로운 화면을 이전 화면 위에 계속 추가하는 방법도 있지만, 이전 화면을 제거하고 새로운 화면을 추가하거나, 전전 화면으로 이동한 후, 새로운 화면을 추가하는 등 다양항 방법으로 화면 이동을 구현해야 할 경우가 있습니다.

GetX에서도 다음과 같은 기능을 사용하여 이를 구현할 수 있습니다.

Get.until

  • 주어진 조건을 만족하는 화면까지 화면을 제거합니다.
  • Navigation.popUntil()와 같은 기능을 합니다.
  • Get.until((route) => Get.currentRoute == '/home')와 같이 사용합니다.

Get.off

  • 현재 화면을 제거하고, 새로운 화면을 추가합니다.
  • Navigation.pushReplacement()와 같은 기능을 합니다.
  • Get.off(Second())와 같이 사용합니다.

Get.offNamed

  • 이름있는 라우트를 사용하여 현재 화면을 제거하고 새로운 화면을 추가합니다.
  • Navigation.pushReplacementNamed()와 같은 기능을 합니다.
  • Get.offNamed('/second')와 같이 사용합니다.

Get.offAndToNamed

  • 이름있는 라우트를 사용하여 새로운 화면을 추가한 후, 이전 화면을 제거합니다.
  • Navigation.popAndPushNamed()와 같은 기능을 합니다.
  • Get.offAndToNamed('/second')와 같이 사용합니다.

Get.offUntil

  • 주어진 조건을 만족하는 화면까지 화면을 제거한 후, 새로운 화면을 추가합니다.
  • Navigation.pushAndRemoveUntil()와 같은 기능을 합니다.
  • Get.offUntil(page, (route) => (route as GetPageRoute).routeName == '/home')와 같이 사용합니다.

Get.offNamedUntil

  • 이름있는 라우트를 사용하여 주어진 조건을 만족하는 화면까지 화면을 제거한 후, 새로운 화면을 추가합니다.
  • Navigation.pushNamedAndRemoveUntil()와 같은 기능을 합니다.
  • Get.offNamedUntil(page, ModalRoute.withName('/home'))와 같이 사용합니다.

Get.removeRoute

  • 주어진 조건을 만족하는 화면을 제거합니다.
  • Navigation.removeRoute()와 같은 기능을 합니다.
  • Get.removeRoute(ModalRoute.withName('/home'))와 같이 사용합니다.

Get.offAll

  • 모든 화면을 제거한 후, 새로운 화면을 추가합니다.
  • Navigation.pushNamedAndRemoveUntil()와 같은 기능을 합니다.
  • Get.offAll(Second())와 같이 사용합니다.

Get.offAllNamed

  • 이름 있는 라우트를 사용하여 모든 화면을 제거한 후, 새로운 화면을 추가합니다.
  • Navigation.pushNamedAndRemoveUntil()와 같은 기능을 합니다.
  • Get.offAllNamed('/second')와 같이 사용합니다.

애니메이션

GetX에서는 다음과 같이 GetPageTransition을 추가하여 화면이 표시될 때, 애니메이션을 결정할 수 있습니다.

getPages: [
  GetPage(name:"/", page: () => Home()),
  GetPage(name:"/second", page: () => Second(), transition: Transition.leftToRight),
]

다음과 같은 애니메이션을 사용할 수 있습니다.

  • Transition.fade,
  • Transition.fadeIn,
  • Transition.rightToLeft,
  • Transition.leftToRight,
  • Transition.upToDown,
  • Transition.downToUp,
  • Transition.rightToLeftWithFade,
  • Transition.leftToRightWithFade,
  • Transition.zoom,
  • Transition.topLevel,
  • Transition.noTransition,
  • Transition.cupertino,
  • Transition.cupertinoDialog,
  • Transition.size,
  • Transition.native

또한 다음과 같이 애니메이션을 상세하게 설정할 수 있습니다.

GetPage(
  name: "/second",
  page: () => SecondScreen(),
  transition: Transition.rightToLeft,
  transitionDuration: const Duration(milliseconds: 400),
  curve: Curves.fastOutSlowIn,
)

스와이프하여 뒤로가기

GetX에서는 다음과 같이 popGesture을 사용하여 스와이프하여 뒤로가기 기능을 조절할 수 있습니다.

GetPage(
  name: "/second",
  page: () => SecondScreen(),
  popGesture: true,
)

popGesturetrue인 경우, 스와이프하여 뒤로가기 기능을 사용할 수 있으며, false인 경우 스와이프하여 뒤로가기 기능을 사용할 수 없습니다.

이전 화면 확인

GetX에서는 다음과 같이 이전 화면이 무엇인지 알 수 있습니다.

Get.previousRoute

완료

이것으로 GetX를 사용하여 Flutter에서 라우트를 관리하는 방법에 대해서 알아보았습니다. 또한 화면 이동을 위한 다양한 방법과, 파라메터를 전달하는 방법 등 라우트를 사용하는 다양항 방법에 대해서도 알아보았습니다.

제 블로그가 도움이 되셨나요? 하단의 댓글을 달아주시면 저에게 큰 힘이 됩니다!

앱 홍보

책 홍보

블로그를 운영하면서 좋은 기회가 생겨 책을 출판하게 되었습니다.

아래 링크를 통해 제가 쓴 책을 구매하실 수 있습니다.
많은 분들에게 도움이 되면 좋겠네요.

스무디 한 잔 마시며 끝내는 React Native, 비제이퍼블릭
스무디 한 잔 마시며 끝내는 리액트 + TDD, 비제이퍼블릭
[심통]현장에서 바로 써먹는 리액트 with 타입스크립트 : 리액트와 스토리북으로 배우는 컴포넌트 주도 개발, 심통
Posts