티스토리 뷰

Flutter에서 앱의 사용자 경험을 강화하려면 효율적인 네비게이션이 필수입니다. 특히, Named Route(명명된 경로)는 코드의 가독성을 높이고, 복잡한 네비게이션 구조를 단순화하는 데 중요한 역할을 합니다. 이 글에서는 Named Route를 설정하고 사용하는 방법을 알아보며, Flutter 프로젝트에서 효율적으로 적용할 수 있는 팁을 제공합니다.

참고. Navigate with named routes

Named Route란 무엇인가?

Named Route는 Flutter의 네비게이션 시스템에서 경로(Route)를 이름으로 관리하는 방법입니다. 화면 전환 시 이름을 통해 특정 페이지를 호출할 수 있어 가독성이 높아지고 유지 보수가 용이합니다.

Named Route의 장점

  1. 가독성:
    • 각 화면에 이름을 부여하여 코드를 직관적으로 관리할 수 있습니다.
  2. 유지보수 용이:
    • 앱이 커질수록 경로를 체계적으로 관리할 수 있습니다.
  3. 중복 코드 감소:
    • 복잡한 네비게이션 구조를 간소화하고, 반복적인 코드 작성을 줄여줍니다.

Named Route 설정하기

1. 기본 설정

Named Route를 사용하려면 MaterialApp 위젯의 routes 속성을 활용해야 합니다.

void main() {
  runApp(MaterialApp(
    initialRoute: '/',
    routes: {
      '/': (context) => FirstScreen(),
      '/second': (context) => SecondScreen(),
    },
  ));
}

class FirstScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('First Screen')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/second');
          },
          child: Text('Go to Second Screen'),
        ),
      ),
    );
  }
}

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back to First Screen'),
        ),
      ),
    );
  }
}

주요 단계별 설명

1. initialRoute 정의

initialRoute는 앱이 실행될 때 표시될 초기 화면을 설정합니다. 일반적으로 '/'를 기본 경로로 사용합니다.

2. routes 맵 구성

routes는 경로 이름과 위젯을 매핑하는 역할을 합니다. { '/routeName': (context) => WidgetName() } 형식으로 정의합니다.

3. 화면 전환

Navigator.pushNamed를 사용하여 지정된 경로로 이동할 수 있습니다.

Navigator.pushNamed(context, '/second');

데이터 전달과 반환

Named Route를 사용하면서 화면 간 데이터를 전달하거나 반환하는 방법도 간단합니다.

데이터 전달

Navigator.pushNamed(
  context,
  '/second',
  arguments: 'Hello from First Screen!',
);

데이터 수신

ModalRoute.of(context).settings.arguments를 사용하여 데이터를 수신할 수 있습니다.

class SecondScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final args = ModalRoute.of(context)!.settings.arguments as String;
    return Scaffold(
      appBar: AppBar(title: Text('Second Screen')),
      body: Center(child: Text(args)),
    );
  }
}

팁: 복잡한 네비게이션 구조 관리하기

  1. Dynamic Route:
    • onGenerateRoute를 사용하면 경로가 동적으로 생성되도록 설정할 수 있습니다.
  2. 중앙화된 Route 관리:
    • 경로를 한 곳에서 정의하여 일관성을 유지합니다.
  3. Error Handling:
    • 정의되지 않은 경로에 대한 오류를 처리하려면 onUnknownRoute를 사용하세요.

Named Route 사용 시 고려 사항

  • 소규모 앱: Named Route는 작은 앱에서도 효율적입니다.
  • 대규모 앱: 앱이 커질수록 onGenerateRoute와 같은 동적 라우팅 방식과 함께 사용하는 것이 효과적입니다.

결론

Flutter의 Named Route는 코드 가독성을 높이고 유지보수를 간소화하는 강력한 도구입니다. 화면 전환이 빈번하거나 네비게이션 구조가 복잡한 앱에서 특히 유용합니다. 위의 내용을 바탕으로 Named Route를 활용하여 깔끔하고 효율적인 Flutter 프로젝트를 구축해보세요!

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      title: 'Named Routes Demo',
      // Start the app with the "/" named route. In this case, the app starts
      // on the FirstScreen widget.
      initialRoute: '/',
      routes: {
        // When navigating to the "/" route, build the FirstScreen widget.
        '/': (context) => const FirstScreen(),
        // When navigating to the "/second" route, build the SecondScreen widget.
        '/second': (context) => const SecondScreen(),
      },
    ),
  );
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('First Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          // Within the `FirstScreen` widget
          onPressed: () {
            // Navigate to the second screen using a named route.
            Navigator.pushNamed(context, '/second');
          },
          child: const Text('Launch screen'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          // Within the SecondScreen widget
          onPressed: () {
            // Navigate back to the first screen by popping the current route
            // off the stack.
            Navigator.pop(context);
          },
          child: const Text('Go back!'),
        ),
      ),
    );
  }
}