본문 바로가기
개발자 랩실/플러터 (Flutter)

Flutter에서 화면 이동 - Navigator

by sina.dev 2022. 1. 13.
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);
        },
      ),
    );
  }
}

댓글