OPENCOURSE바이브 코딩으로 배우는 Flutter 첫걸음

챕터 3 / 5

위젯 트리 이해하기

예상 70분 · 소단원 3 · 앞 챕터 2 첫 프로젝트 만들기에서 이어져요

영상을 준비하고 있어요

브라우저에서 조립해 재생해요 — 보통 몇 초면 끝나요

3.1위젯이 뭐예요

2장에서 '나의 첫 앱'을 실행해 봤어요. 화면에는 제목 막대와 글자 한 줄이 떠 있었죠. 이 화면은 무엇으로 만들어졌을까요? 답은 위젯이에요.

위젯은 화면을 이루는 부품이에요. 버튼도 위젯이고, 글자도 위젯이에요. 글자 둘레의 여백도 위젯이고, 화면 전체도 하나의 큰 위젯이에요. Flutter 공식 문서는 이를 "모든 것이 위젯"이라고 말해요. 눈에 보이는 것부터 자리만 잡아 주는 것까지, 화면의 전부가 부품 하나하나로 되어 있다는 뜻이에요.

부품은 혼자 있지 않아요. 위젯은 다른 위젯을 품어요. 품는 쪽을 부모라고 하고, 안기는 쪽을 자식이라고 불러요. 화면 전체를 맡는 위젯이 제목 막대 위젯을 품고, 제목 막대 위젯이 글자 위젯을 품는 식이에요.

부모가 자식을 품고, 그 자식이 또 자식을 품으면서 쌓인 전체 모양을 트리라고 해요. 나무를 뒤집은 모양의 구조도라서 붙은 이름이에요. 맨 위에 뿌리가 하나 있고, 아래로 가지가 뻗어 나가요.

첫 화면의 위젯 트리. MaterialApp이 Scaffold를 품고, Scaffold가 AppBar와 Center를 품으며, AppBar 아래에 Text '나의 첫 앱', Center 아래에 Text '안녕, Flutter!'가 잎으로 매달려 있다.
그림 1 — 코드와 같은 구조의 트리를 눈으로 확인하게 한다

위 그림이 바로 '나의 첫 앱' 화면의 트리예요. 방금 본 트리 그림 안에는 MaterialApp, Scaffold, AppBar, Center, Text라는 낯익은 이름들이 보여요. 2장의 코드에서 이름만 스쳐 봤던 것들이 사실 전부 위젯이었어요.

트리의 맨 위, 곧 뿌리는 MaterialApp이에요. 화면 전체를 품는 가장 큰 부모예요. 반대로 맨 끝에 매달린 Text는 더는 아무도 품지 않는데, 나무 가지 끝의 잎 같다고 해서 잎이라고 불러요. 우리가 화면에서 실제로 본 글자가 바로 이 잎, 곧 Text 위젯이에요.

이 소단원을 정리할게요. 위젯은 화면의 부품이에요. 부모가 자식을 품으면서 트리를 이뤄요. 코드를 읽을 때 이 트리를 머릿속에 그려 보세요. 트리를 그리면 어떤 위젯이 어떤 위젯을 품는지가 한눈에 들어와요.

3.2트리 읽는 법

3.1에서 화면 전체가 트리라는 걸 봤어요. 그런데 코드 어디에 그 트리가 숨어 있을까요? 답은 줄 앞의 빈칸, 곧 들여쓰기예요. 규칙은 하나뿐인데, 코드가 안으로 들어갈수록(들여쓰기가 깊을수록) 자식이라는 거예요.

2장에서 실행해 본 코드를 다시 볼게요.

runApp(
  MaterialApp(
    home: Scaffold(
      appBar: AppBar(title: Text('나의 첫 앱')),
      body: Center(
        child: Text('안녕, Flutter!'),
      ),
    ),
  ),
);

코드의 들여쓰기를 따라 트리를 소리 내어 읽어 볼게요. "MaterialApp이 Scaffold를 품고, Scaffold가 AppBar와 Center를 품고, Center가 Text를 품는다." 한 칸 더 안쪽에 있으면 그 위젯의 자식이라는 뜻이에요. 계단을 내려가듯 읽으면 돼요.

코드에는 자식을 넣는 자리에 이름표가 붙어 있어요. child예요. 영어로 '자식'이라는 뜻이에요. child: 다음에 오는 위젯이 곧 자식이에요. 위 코드에서 Center의 child는 Text죠. 그래서 "Center가 Text를 품는다"라고 읽은 거예요.

트리를 읽을 줄 알면 두 가지가 달라져요. 첫째, AI가 만든 코드가 어떤 화면이 될지 실행 전에 그려 볼 수 있어요. 코드를 읽고 판단하는 사람의 몫, 1장에서 말한 바이브 코딩의 절반이 바로 이거예요. 둘째, 트리를 읽을 줄 알면 AI에게 부탁하는 프롬프트가 더 구체적으로 좋아져요. "위쪽에 제목 막대, 가운데에 인사말을 놓아 줘"처럼 구조로 부탁할 수 있으니까요.

짧은 연습 하나 해 볼까요. 위 코드를 보고 종이에 네모와 선으로 트리를 그려 보세요. 위젯 하나가 네모 하나, 품는 관계가 선 하나예요. 3.1에서 본 트리 그림과 비슷하게 나오면 제대로 읽은 거예요.

3.3트리 고쳐 그리기

화면을 바꾸고 싶을 때가 왔어요. 이럴 때 코드부터 열면 길을 잃기 쉬워요. 코드보다 먼저 위젯 트리 그림을 고쳐 그려요. 어디에 무엇이 들어갈지 그림으로 정한 다음에 부탁하는 거예요.

2장에서 만든 '나의 첫 앱'에 버튼을 하나 넣어 볼게요. 가운데 인사말 아래에 '눌러 보세요' 버튼을 두고 싶어요. 지금 트리에서 Center의 자식은 Text 하나예요. 그런데 버튼이 들어오면 자식이 둘이 돼요. Center의 child 자리는 하나뿐이라, 두 자식을 넣을 수 없어 곤란해요. 그래서 Center와 Text 사이에 새 위젯이 하나 필요해요. 그 위젯이 Column이에요. Column은 자식들을 세로로 나란히 늘어놓는 위젯이에요. Center의 자식 자리에 Column을 넣고, Column의 자식으로 Text와 버튼을 두면 돼요.

버튼 추가 전후의 트리 비교. 왼쪽(바꾸기 전)은 Center가 Text 하나를 품고, 오른쪽(바꾼 뒤)은 Center가 Column을 품고 Column이 Text와 ElevatedButton 두 자식을 나란히 품는다.
그림 2 — 자식이 둘이 될 때 Column이 필요한 이유를 전후 비교로 보게 한다

그림이 바꾸기 전과 후의 트리예요. Text가 Column 아래로 한 칸 내려가고, 그 옆에 버튼이 생겼어요. 트리가 이렇게 머리에 있으면 부탁이 구체적으로 나와요. "가운데 인사말 아래에 '눌러 보세요' 버튼을 추가해 줘." 어디에, 무엇을, 어떤 글자로 — 필요한 내용이 한 문장에 다 들어 있어요.

AI가 코드를 돌려주면 확인할 곳도 이미 알고 있어요. 확인할 곳은 Column이 생겼는지, 그 Column의 자식이 둘인지예요. 앞에서 익힌 대로 들여쓰기를 보면 돼요. Column보다 한 단 더 들어간 줄이 두 개면 자식이 둘이라는 뜻이에요. 하나라도 다르면 그림과 코드를 대조해서 다시 부탁하면 돼요.

정리해 볼게요. 그림 먼저, 부탁은 그다음, 코드는 확인. 이 순서가 이번 챕터에서 익힌 습관이에요. 트리를 그릴 줄 알면 바꾸고 싶은 화면을 정확히 말할 수 있고, 돌아온 코드도 스스로 판단할 수 있어요.