본문 바로가기

개발/Flutter

Flutter 화면 이동

반응형

Flutter에서의 Navigator를 통한 기본 화면이동에 대해서 알아보겠다.


일반적인 화면 이동

앱화면 안에서 다른 widget페이지로 이동하고 싶을 때에는

Material/Cupertino의 Navigator를 이용해서 이동하게 되는데

Navigator이용 방법은 다음과 같다. 

 

이동  

다음과 같이 코드를 넣는다.
Navigator.push(context, MaterialPageRoute(builder:(context) =>이동할 페이지()))

 

복귀 

다시 돌아올때는
Navigator.pop() 을 호출 한다.

 

또는 뒤로가기를 통해 되 돌아 갈 수 있다.

 

 

간단한 샘플 소스를 보면 다음과 같다. 

import 'package:flutter/material.dart';  

void main() {  
  //MaterialApp 이 Route를 가능하게 해준다.  
  runApp(const MaterialApp(home: MainPage()));  
}  

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

  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: const Text('화면바꾸기'),  
      ),  
      body: Center(  
        child: ElevatedButton(  
          onPressed: () {  
            //화면이동 -> 두번째 페이지로 이동하기  
            Navigator.push(  
              context,  
              MaterialPageRoute(  
                builder: (context) => const SecondPage(),  
              ),  
            );  
          },  
          child: const Text('Main'),  
        ),  
      ),  
    );  
  }  
}  

//두번째 페이지  
class SecondPage extends StatelessWidget {  
  const SecondPage({Key? key}) : super(key: key);  

  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: const Text('Second'),  
      ),  
      body: Column(  
        mainAxisAlignment: MainAxisAlignment.center,  
        children: [  
          const Center(  
            child: Text('두번째페이지'),  
          ),  
          ElevatedButton(  
            onPressed: () {  
              //돌아가기 (뒤로가기 버튼과 같은 동작을 한다.)
              Navigator.pop(context);  
            },  
            child: const Text('돌아가기'),  
          ),  
        ],  
      ),  
    );  
  }  
}

 

BottomNavigationBar

 

하단 탭바를 통해서 화면을 전환하는 경우는

위의 화면이동과는 다르게 BottomNavigationBar를 설정하는 형식으로 구현 가능하다.

 


BottomNavigationBar를 작성하는데 중요한 값으로는 다음값들이 있는데 하나씩 알아보자면

currentIndex : 선택한 탭의 인덱스를 알려주는 역할을 한다.
onTap : 탭이 선택될때 index가 넘어 온다. 넘어오는 index를 통해 state를 바꿀수 있다.
items : 탭에 표현되는 item들

 

BottomNavigationBar를 이용해 만든 간단한 샘플 소스 이다. 

import 'package:flutter/material.dart';  

void main() {  
  runApp(const MyApp());  
}  

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

  @override  
  Widget build(BuildContext context) {  
    //프로젝트 만들면 기본으로 적용 되는 MaterialApp    return const MaterialApp(  
      home: Main(),  
    );  
  }  
}  

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

  @override  
  State<Main> createState() => _MainState();  
}  

class _MainState extends State<Main> {  
  var _currentIndex = 0;  

  //하단 탭바를 통해 보여줄 화면 widget  final _widgets = [const FirstPage(), const SecondPage()];  

  @override  
  Widget build(BuildContext context) {  
    return Scaffold(  
      appBar: AppBar(  
        title: const Text('BottomNavigation'),  
      ),  
      body: Container(  
        decoration: const BoxDecoration(color: Colors.red),  
        child: Column(  
          crossAxisAlignment: CrossAxisAlignment.stretch,  
          mainAxisAlignment: MainAxisAlignment.center,  
          children: [  
            //하단 탭에서 선택을 통해 index가 변경되고  
            //변경된 index에 따라서 list에서 화면을 변경해서 보여줌  
            _widgets[_currentIndex],  
          ],  
        ),  
      ),  
      bottomNavigationBar: BottomNavigationBar(  
        //탭바의 선택 화면을 보여주기 위해서 index연결  
        currentIndex: _currentIndex,  
        onTap: (index) {  
          setState(() {  
            //탭 클릭으로 index 변경  
            _currentIndex = index;  
          });  
        },  
        items: const [  
          //하단 탭바 아이템 설정  
          BottomNavigationBarItem(  
              label: 'Main', icon: Icon(Icons.shopping_bag)),  
          BottomNavigationBarItem(  
              label: 'Second', icon: Icon(Icons.shopping_bag)),  
        ],  
      ),  
    );  
  }  
}  

//기본 메인 페이지  
class FirstPage extends StatelessWidget {  
  const FirstPage({Key? key}) : super(key: key);  

  @override  
  Widget build(BuildContext context) {  
    return Column(  
      children: [  
        const Center(child: Text('MainPage')),  

        //화면에 버튼 설정  
        GestureDetector(  
          onTap: () {  
            //탭바 상태에서 Navigator.push를 통한 화면 전환  
            //전체화면 변경 (탭을 가리는 화면전환)  
            Navigator.push(context,  
                MaterialPageRoute(builder: (context) => const SecondPage()));  
          },  
          child: const Center(  
              child: Padding(  
            padding: EdgeInsets.all(20.0),  
            child: Text('Go NextPage'),  
          )),  
        ),  
      ],  
    );  
  }  
}  


//두번째 화면으로 쓰이는 화면 class SecondPage extends StatelessWidget {  
const SecondPage({Key? key}) : super(key: key);  

  @override  
  Widget build(BuildContext context) {  
    return const Expanded(child: Scaffold(body: Text('Second')));  
  }  
}

 


 

이동했던 화면의 선택값(결과값을 넘겨줄때는?)

 

Navigator.push를 통해 반환되는 값은 이동한 화면에서 전달하는 값이다. 

Navigator.pop을 통해서 이전 화면으로 돌아갈때 넘겨 줘야 할 값을 같이 보내면 된다. 

아래 예제는 화면이동 예제에서 결과 값을 받는 부분을 추가한 샘플소스이다. 

 

Navigator의 push와 pop을 주의 깊게 보자.

import 'package:flutter/material.dart';

void main() {
  //MaterialApp 이 Route를 가능하게 해준다.
  runApp(const MaterialApp(home: MainPage()));
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('화면바꾸기'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () async {
            //화면이동 -> 두번째 페이지로 이동하기 결과값 받기 
            var result = await Navigator.push(
              context,
              MaterialPageRoute(
                builder: (context) => const SecondPage(),
              ),
            );

            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(
                content: Text('$result'),
              ),
            );
          },
          child: const Text('Main'),
        ),
      ),
    );
  }
}

//두번째 페이지
class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Center(
            child: Text('두번째페이지'),
          ),
          ElevatedButton(
            onPressed: () {
              // pop 하면서 값 전달하기
              Navigator.pop(context, 'Back 1');
            },
            child: const Text('돌아가기 one'),
          ),
          ElevatedButton(
            onPressed: () {
              // pop 하면서 값 전달하기
              Navigator.pop(context, 'Back 2');
            },
            child: const Text('돌아가기 two'),
          ),
        ],
      ),
    );
  }
}

 

 

 


마치며... 

 

MaterialApp과 CupertinoApp에서 제공하는 route기능으로 화면이동에 대해서 살펴봤다. 

push와 pop을 통한 이동과 결과값 전달을 통해 이제는 Flutter에서 화면이동을 쉽게 할 수 있다. 

 

 

 


 

MaterialApp Widget에 대한 간단 설명

 

Navigator를 사용하여 route를 하려면 기본 조건은 Main Widget은 MaterialApp으로 감싸져 있는 조건으로 시작한다.
Flutter 프로젝트를 만들면 기본으로 만들어지는 MyApp Widget의 MaterialApp Widget말이다.

 

MaterialApp Widget이 중요한 이유는

기본적으로 MaterialApp Widget이 route기능을 기본으로 제공하고 있기 때문이다.


MaterialApp Widget의 파라미터 속성으로 routes라고 하는 속성도 실제 화면이동값을 path로 설정할 때 씌인다.

CupertinoApp의 경우도 MaterialApp과 동일하다. 

 

https://api.flutter.dev/flutter/material/MaterialApp-class.html

 

MaterialApp class - material library - Dart API

An application that uses material design. A convenience widget that wraps a number of widgets that are commonly required for material design applications. It builds upon a WidgetsApp by adding material-design specific functionality, such as AnimatedTheme a

api.flutter.dev

위 링크중 참고할 예를 들면 다음과 같다.

MaterialApp(  
  routes: <String, WidgetBuilder>{  
    '/': (BuildContext context) {  
      return Scaffold(  
        appBar: AppBar(  
          title: const Text('Home Route'),  
        ),  
      );  
    },  
    '/about': (BuildContext context) {  
      return Scaffold(  
        appBar: AppBar(  
          title: const Text('About Route'),  
        ),  
      );  
    }  
  },  
)
반응형

'개발 > Flutter' 카테고리의 다른 글

Flutter Column/Row  (0) 2022.04.19
Flutter Text Widget  (0) 2022.04.18
Flutter ListView  (0) 2022.04.08
Flutter http 패키지와 api 통신 하기  (0) 2022.04.07
Flutter Json to model  (0) 2022.04.07