Flutter 1부터 배우기 : 화면이 2개 있는 단순 앱 -3 [Navigator Class]

개발하자 백조·2022년 12월 8일
2
post-thumbnail

아직 2편을 안 봤다면? 보러가기👀


반갑습니다 여러분! 코딩백조입니다🦢

오늘 드디어 화면 왔다갔다를 구현할 예정입니다!!
거의 다 왔어요 😉 화이팅!

📍[ 3 / 3 ] 메인 페이지의 버튼 누르면 두 번째 페이지로 이동하기
. . . 두 번째 페이지의 뒤로가기 버튼 누르면 메인 페이지로 이동하기

지난 시간에 Navigator이 페이지를 관리한다는 것까지 말씀드렸어요.
어떻게 관리하냐면요..
바로 Stack 이라는 것을 통해서 입니다!

그래서 Stack이 뭔데? 😡

Stack 은 한국어로 "쌓다" 라는 뜻이 있는데요, 그릇 쌓인거 생각하시면 됩니다.ㅋㅋ

접시를 정리할 때 보통 위로 위로 쌓다가 쓸 땐 또 위에서부터 꺼내 쓰잖아요,
우리에게 보이는 페이지도 그렇게 움직인다는 사실!! 🤩

파란색 통 안에 첫 번째 페이지인 Screen 1 이 있네요.
사용자는 맨 위만 볼 수 있으니 첫 화면을 볼거에요.

이제 버튼을 눌러볼까요?
푸시!! Push 라는 함수를 통해 네비가 Screen 2를 통에 넣어줍니다!

사용자는 맨 위만 볼 수 있기 때문에 이젠 Screen 2만 보이겠죠?

만약 사용자가 뒤로가기를 누른다면?
팝!! Pop 이라는 함수를 통해 네비가 Screen 2를 구멍에서 뺍니다.

그러면 이젠 구멍에 Screen 1 만 있으니까 다시 첫 번째 화면이 보이겠죠!

이런 식으로 Navigator 가 Route 들을 관리한답니다 😎 신기하지 않나요?


우리도 구현하러 가야죠!!

ElevatedButton 을 눌렀을 때 화면을 이동하고 싶은거니까
onPressed 함수에 코드를 작성해볼게요!

아직은 (){} 의 빈 함수지만, 이제 넣어볼게요.
중괄호 내부에다 작성 시작입니다!!

아까 말했듯, 새로운 화면을 넣는 함수는?
Push 💨 해줍니다!

Navigator.push 를 입력해볼까요?

이 두개는 Navigator.push 의 필수 요소입니다. 역시 알아봐야겠죠?

context

앞으로 정말정말 많이 볼 친구입니다.
지금은 중요한게 아니니, 간단하게는 "주소" 정도라고 해둡시다! 위젯이 여러개가 있는데 그 중 내 위치가 어딘지를 저장해주는 변수입니다.ㅎㅎ

route

어! 우리가 아는 단어에요!
맞아요, 바로 페이지를 의미합니다. 🏞 어느 페이지를 보여줄거야? 라고 묻는거죠.

여기서 나올 코드는 좀 복잡해서 일단은 따라 써봅시다!

route를 지우고 그 자리에 MaterialPageRoute 를 입력해주세요!

builder 부분에 이제 우리의 페이지를 넣어주면 되는데요, 좀 특이한 형태로 넣어줄 겁니다.

builder: (_) {
  return PhotoScreen();
}

아니면

builder: (_) => PhotoScreen()

둘 중 하나를 골라 입력해줍시다!

저 언더바는 뭐고 갑자기 화살표는 뭐고.. 궁금한게 많으시죠?

매개변수로써의 언더바 (_)

저도 처음 플러터 배울 때 아무도 설명을 안해줘서 답답했었는데요,
매개변수를 필요로 하는 함수에서

🤨 "근데 나 매개변수 안쓸건데?"
라는 의미로 쓰입니다.

사실 저 builder: 은 context 라는 변수를 매개변수로 받거든요.

builder: (context) {
  return PhotoScreen();
}

원래는 이렇게 써야 완벽한 형태가 되는거죠!
근데, 우리는 context 라는 변수 받아봤자.. { 중괄호 } 안에서 안쓰잖아요. 그래서 쓸데없다고 알려주는 표시랍니다.
물론 나중에 context를 써야 하면 꼭 붙여야겠죠!

return, 그리고 =>

갑자기 화살표?! 당황하셨을 수도 있는데요,
arrow function, 화살표 함수라는 것도 있습니다.

플러터의 언어인 Dart 에서는 한줄짜리 리턴문을 => 로 대체해서 사용할 수 있어요! 🤭
처음엔 구조가 잘 안보여서 중괄호를 선호했는데.. 이젠 이게 더 편하더라구요 😮

위에 (_) 를 쓰는 이유를 알았으면, 이제 => 로 바꿔볼게요!

builder: (context) => PhotoScreen()

훨씬 깔끔하죠?ㅎㅎ


휴, 엄청 많은 내용이 지나갔어요 😮‍💨

이제 코드가 거의 다 된거같은데요?

여러분의 버튼 코드가 이렇게 생겼나요?ㅎㅎ
그렇다면 바로 실행해봅시다!!

              ElevatedButton(
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(builder: (_) => PhotoScreen()),
                  );
                },
                child: const Text("cat photo"),
              ),

안드로이드 스튜디오에서는 에뮬레이터라고 하는 기능이 있어요.
가상 핸드폰을 만들 수 있는거죠!

에뮬레이터가 없어요..😅

여기서 자신이 사용하는 폰을 선택해주고,
화면 오른쪽에 핸드폰이 나타나면 저 오른쪽 위에 초록색 삼각형을 눌러 Run ▶️ 해줍니다!

시간이 얼마나 오래 걸리는지는 여러분 컴퓨터의 성능에 따라..😣
전 지금 맥을 써서 10초도 안걸리는데 예전에 3년된 삼성 노트북으로 돌리니까 5분이 넘게 걸리더라구요.....🤬 진짜 화나지만 인내의 시간을 가져봅니다..

..

성공! 이 되어야 됩니다. 호옥시 빌드 실패했다면 에러 코드를 댓글로 남겨주세요!

어떤가요? 앱이 보이나요? 페이지가 잘 넘어가나요?!

아니죠!!! 이상한 에러가 뜹니다!!

혹시 자세한 이유와 자세한 해결방법이 궁금하시다면 여기서 확인해주세요! 👀
이 글에서는 간단하게 해결 방법만 얻고 넘어가겠습니다!!

나중에 앱 다 만들면 한 번 보시는걸 추천해요 😜

해결은 엄청 쉬워요.
main.dart 파일로 넘어가서,
5번째 줄 runApp(const MyApp()); 부분을 수정해줄겁니다!

이거 하나만 추가해주면 돼요.
MyApp을 MaterialApp로 감쌀겁니다!
이렇게 입력해주세요.

다시 Run 해볼까요?

두근두근하는 마음으로 버튼을 누르면..

성공!! 전 잘 넘어가네요 🥳 귀여운 고양이가 보입니다!

아직 끝나지 않았어요!!

메인 화면에서 고양이 화면으로 넘어가긴 했는데.. 다시 돌아올 방법이 없어요 😢
그러나! 우린 아까 Navigator 의 존재를 배웠으니 할 수 있어요!!

화면 맨 위에 <- 이렇게 생긴 화살표로 돌아가면 좋을 거 같아요. 이건 얼마 안걸리니까 바로 해봅시다!


파란색 배너 부분을 우리는 AppBar 이라고 부릅니다.

이 AppBar을 자세히 뜯어보면,

여러 속성이 있어요. 우리가 쓰는 title 도 보이네요!

자, 암기입니다. 제목 왼쪽의 공간은 바로

leading 🔙 📂

입니다!!

보통은 뒤로가기나, 햄버거 메뉴🍔를 놓는 곳이죠.

여기에 뒤로가기 아이콘을 사용한 버튼을 주고, 사용자가 버튼을 눌렀을 때 현재 페이지를 Stack 에서 빼내면 되겠죠?

바로 들어갑니다!!

photo_screen.dart 에 들어가서 편집 해봐요!

PhotoScreen 위젯의 AppBar 내부에 작성해줄거에요.

title: ~~, 다음에 leading 을 입력해줍니다.
그리고 아이콘 버튼을 넘겨줄 겁니다!

따라치면서 대충 이런게 있군~ 하시면 됩니다. 😜


Elevated Button 이랑 비슷하죠?
child: 대신 icon: 으로 바뀌었을 뿐입니다!

icon에는 icon: Icon(Icons.arrow_back) 라고 Icon() 위젯을 넣어줍니다!
Icons.arrow_back 이라는 모양을 Icon() 위젯에 넘겨준 형태라고 생각하면 됩니다.

이제 onPressed 차례!

지금 우리의 Stack 에는 MyApp 위에 PhotoScreen 이 놓아져 있는 형태일거에요.
다시 MyApp을 보여주려면 어떻게 해야 할까요?

맞아요, 바로 POP! 해줘야 합니다! 😉

이렇게 입력해주세요.

onPressed: (){}
아까처럼 빈 함수를 만들고, 중괄호 부분에 Navigator.pop 을 입력해줍니다.

세미콜론 조심! 👀 이렇게 (){ "여기" } 함수 내부에서는 모든 문장이 ; 로 끝난답니다!

다시 Run▶️ 을 눌러볼까요?
앱이 다시 실행되면 cat photo 버튼을 눌러봅시다!

오! 성공적으로 버튼이 생겼어요!!

뒤로가기 버튼을 누르면 이제 다시 메인 화면으로 가는 것을 볼 수 있습니다. 🤩 🥳

다들 성공하셨나요? 😎

첫 번째 앱 만들기, 끝입니다! 🥳

모두 수고하셨어요 🥰
그럼, 다음에 만나요!


main.dart

import 'package:flutter/material.dart';
import 'package:navigator_example/photo_screen.dart';

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

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

  
  MyAppState createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("고양이 사진 보여줘!"),
        ),
        body: Center(
          child: Column(
            children: [
              const SizedBox(
                height: 100,
              ),
              const Text("press here to see cat photo"),
              ElevatedButton(
                onPressed: () {
                  Navigator.push(
                    context,
                    MaterialPageRoute(
                      builder: (_) => const PhotoScreen(),
                    ),
                  );
                },
                child: const Text("cat photo"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

photo_screen.dart

import 'package:flutter/material.dart';

class PhotoScreen extends StatelessWidget {
  const PhotoScreen({Key? key}) : super(key: key);
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text("cat photo"),
          leading: IconButton(
              onPressed: () {
                Navigator.pop(context);
              },
              icon: const Icon(Icons.arrow_back)),
        ),
        body: const Center(
          child: Image(
            image: NetworkImage(
                "https://images.pexels.com/photos/416160/pexels-photo-416160.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=2"),
          ),
        ),
      ),
    );
  }
}
profile
개발자로서 100가지 일을 해보고 싶은 조경현의 개발 블로그

0개의 댓글