개발자 랩실/플러터 (Flutter)

Flutter에서 화면 이동 - Navigator

sina.dev 2022. 1. 13. 23:07
728x90

목차

 

Navigator 사용 이유

우리가 사용하는 앱은 단일 페이지로 되어 있지 않고 대부분 화면을 이동한다. 리스트 뷰의 아이템을 선택하면 다음 화면으로 이동하는데, 이는 우리에게 매우 익숙한 UI이다. 화면을 이동할 때 사용하는 게 Flutter의 Navigator을 이용해 화면을 이동한다.

 

 

Stack

스택은 Last In First Out의 특징을 갖는다. 네비게이터 또한 스택처럼 Last In First Out 방식으로 네비게이션 스택을 관리한다. 페이지를 Navigator로 이동을 할 때 처음에 보였던 화면이 제일 밑에 깔리고, 최근에 불러온 페이지가 제일 네비게이션 스택의 제일 위에 쌓인다.

 

 

Navigator 사용 방법

화면을 위에 쌓을 땐 Navigator.push() 메소드를 사용하고, 위에 쌓여있는 화면을 제거할 땐 Navigator.pop() 메소드를 사용한다.

Navigator.of(context).push(route);

Navigator.of(context).pop();

 

 

실제 사용 코드

import 'package:flutter/material.dart';

void main() => runApp(const MyHome());

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      home: Scaffold(
        body: SubMain(),
      ),
    );
  }
}

class SubMain extends StatefulWidget {
  const SubMain({Key? key}) : super(key: key);

  @override
  _SubMainState createState() => _SubMainState();
}

class _SubMainState extends State<SubMain> {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      child: const FirstScreen(),
    );
  }
}

/// 첫번째 화면
class FirstScreen extends StatelessWidget {
  const FirstScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: OutlinedButton(
        child: const Text('FirstScreen',
            style: TextStyle(
              color: Colors.blueGrey,
              fontSize: 32,
            )),
        onPressed: () {
          Navigator.push(context,
              MaterialPageRoute(builder: (context) => const SecondScreen()));
        },
      ),
    );
  }
}

/// 두번째 화면
class SecondScreen extends StatelessWidget {
  const SecondScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: OutlinedButton(
        child: const Text('SecondScreen',
            style: TextStyle(
              color: Colors.blueGrey,
              fontSize: 32,
            )),
        onPressed: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}

 

 

Navigator 메소드 종류

  1. Navigator.push()
    • 화면을 불러오기 위해 사용
  2. Navigator.pop()
    • 제일 위에 있는 화면을 제거하기 위해 사용
    • 이전 페이지로 이동할 경우 많이 사용
  3. 'Navigator.of(context).pushNamed('/main’);

 

3. Navigator.of(context).pushNamed('경로명')

여러 개의 페이지를 이동할 경우 경로명을 지정하여 이동할 수 있다. 경로명으로 페이지를 이동할 경우 pushNamed() 메소드를 이용하여 페이지를 이동한다.

 

 

예제

import 'package:flutter/material.dart';

void main() => runApp(const MyHome());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
			/// 초기 페이지 선언
      initialRoute: '/',
			/// 경로별 이동할 페이지 선언
      onGenerateRoute: (settings) {
        switch(settings.name) {
          case '/':
            return MaterialPageRoute(builder: (_) => const SubMain(), settings: settings);
          case '/second':
            return MaterialPageRoute(builder: (_) => const SecondScreen(), settings: settings);
          default:
            return null;
        }
      },
      home: const Scaffold(
        body: SubMain(),
      ),
    );
  }
}

class SubMain extends StatefulWidget {
  const SubMain({Key? key}) : super(key: key);

  @override
  _SubMainState createState() => _SubMainState();
}

class _SubMainState extends State<SubMain> {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: MediaQuery.of(context).size.width,
      height: MediaQuery.of(context).size.height,
      child: const FirstScreen(),
    );
  }
}

/// 첫번째 화면
class FirstScreen extends StatelessWidget {
  const FirstScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: OutlinedButton(
        child: const Text('FirstScreen',
            style: TextStyle(
              color: Colors.blueGrey,
              fontSize: 32,
            )),
        onPressed: () {
          Navigator.of(context).pushNamed('/second');
        },
      ),
    );
  }
}

/// 두번째 화면
class SecondScreen extends StatelessWidget {
  const SecondScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: OutlinedButton(
        child: const Text('SecondScreen',
            style: TextStyle(
              color: Colors.blueGrey,
              fontSize: 32,
            )),
        onPressed: () {
          Navigator.pop(context);
        },
      ),
    );
  }
}