플러터 프로젝트를 생성하면 폴더와 파일이 자동으로 만들어집니다. 이런 폴더와 파일이 어떤 역할을 하는지 살펴보겠습니다.
프로젝트 폴더 구성 알아보기
플러터 프로젝트를 생성하면 하위에 android, ios, lib, test라는 폴더가 자동으로 만들어집니다. 각 폴더는 다음과 같은 용도로 사용합니다.
- android : 안드로이드 앱 구성
- ios (사진에는 없음) : iOS 앱 구성
- lib : 다트 파일
- test : 테스트 다트 파일
플러터는 크로스 플랫폼 개발 프레임워크이므로 프로젝트를 만들 때 설정에 따라 자동으로 android, ios, windows, linux, macos, web 같은 폴더가 만들어질 수 있습니다.
android 폴더 구성은 안드로이드 스튜디오에서 안드로이드 네이티브 앱 프로젝트를 만들 때와 같으며, ios 폴더 구성은 Xcode에서 iOS 네이티브 앱 프로젝트를 만들 때와 같습니다. 결국 플러터 프로젝트를 빌드하면 플랫폼별로 android와 ios 폴더에 구성한대로 앱이 만들어집니다. android와 ios 폴더에 있는 파일을 열어서 작업할 일은 많지 않지만, 플랫폼 채널을 이용하거나 네이티브 기능을 제공하는 패키지를 이용할때는 파일을 열어서 직접 수정하기도 합니다.
lib 폴더에는 다트 파일을 저장합니다. 하위 폴더를 자유롭게 구성해 다트 파일들을 추가해 가면서 앱을 개발합니다. lib 폴더에 앱을 구성하는 다트 파일을 만들어 놓으면 앱을 빌드할 때 lib에 포함된 다트 파일이 플랫폼별 앱에 자동으로 포함됩니다.
test 폴더는 테스트 코드를 별도 폴더에 구성해 앱을 빌드할 때 포함하지 않게 할 목적으로 제공합니다.
프로젝트 파일 구성 알아보기
이번에는 프로젝트를 구성하는 주요 파일을 살펴보겠습니다. 이곳에서 소개하지 않는 파일은 빌드 도구가 자동으로 관리하므로 개발자가 따로 신경 쓰지 않아도 됩니다.
- lib/main.dart : 앱의 메인 다트 파일
- .gitignore: 깃에 업로드하지 않을 파일 등록
- pubspec.yaml : 플러터 프로젝트의 메인 환경 파일
프로젝트를 구성하는 파일 가운데 개발자가 가장 주목할 파일은 lib 폴더에 있는 main.dart입니다. 01장에서 프로젝트를 만들고 안드로이드 에뮬레이터와 iOS 시뮬레이터에서 테스트해 보았습니다. 이때 lib 폴더에 있는 main.dart 파일을 실행했는데 이 파일에는 플러터 엔진이 앱을 실행할 때 진입점인 main() 함수가 들어있습니다. 이처럼 main() 함수가 있는 다트 파일이라면 꼭 main.dart가 아니더라도 실행할 수 있습니다.
그다음 주목할 파일은 플러터 프로젝트의 메인 환경 파일인 pubspec.yaml입니다. 이 파일에는 빌드와 관련된 각종 설정이 포함되어 있어서 자주 열어서 분석하거나 수정합니다. 예를 들어 패키지나 리소스 폴더를 추가하는 작업입니다. 이 부분은 중요한 내용이므로 이후에 자세하게 다루겠지만 여기서는 앱에 어떤 패키지나 리소스를 추가하려면 pubspec.yaml 파일에 등록해 줘야 한다는 사실만 기억하기 바랍니다.
main.dart 파일 분석하기
안드로이드 스튜디오에서 새로운 플터러 프로젝트를 생성하고 실행하면 데모 앱이 실행됩니다. 이는 프로젝트의 main.dart 파일이 실행된 결과입니다. main.dart 파일을 제대로 이해하려면 위젯과 관련된 내용을 알아야 합니다. 위젯은 플러터 앱 개발을 이해하는 데 중요한 부분이지만 앞에서 다루기에는 부담스러울 수 있습니다. 따라서 여기서는 main.dart 파일의 코드가 어떻게 구성됐는지만 살펴보겠습니다.
main.dart 파일을 열어 보면 코드가 여러 줄 있는데 주석을 제거하면 몇 줄만 남습니다. 이 코드들이 무엇을 의미하는지 알아보겠습니다.
import 구문 알아보기
먼저 첫 줄에는 import 구문이 있습니다. import 구문은 다른 다트 파일을 불러올 때 사용합니다. 다른 다트 파일이란 플러터에서 제공하는 패키지일 수도 있고 pubspec.yaml 파일에 등록한 외부 패키지일 수도 있습니다. 또는 개발자가 직접 작성한 다트 파일일 수도 있습니다. 어떤 다트 파일이든지 해당 파일에 선언된 클래스, 함수, 변수 등을 이용하려면 import 구문으로 불러와야합니다.
main() 함수 알아보기
main() 함수는 다트 엔진의 진입점 으로서 다트 엔진이 main()을 호출하면서 앱이 실행됩니다. main() 에서는 runApp() 함수를 호출하고 있습니다. 이때 매개변수로 위젯을 지정했는데, 위젯은 화면을 구성하는 클래스라고 생각하면 됩니다. runApp()에 앱의 첫 화면을 구성할 위젯을 지정한 것이며, 이 위젯의 화면이 나오면서 앱이 실행됩니다.
MyApp 클래스 알아보기
위젯 클래스는 StatelessWidget이나 StatefulWidget 가운데 하나를 상속받아 작성합니다. 두 클래스와 관련해서는 08장에서 자세하게 살펴보겠습니다. 위젯은 화면 구성이 목적이므로 build() 함수에 화면을 어떻게 구성할지 명시해 줍니다. 위젯 클래스가 실행되면 자동으로 build() 함수가 호출되고 이 함수에서 반환한 위젯이 화면에 출력됩니다.
build() 함수를 살펴보면 MaterialApp과 MyHomePage로 화면을 구성했는데 이들도 위젯 클래스 입니다. MaterialApp은 플러터에서 제공하는 위젯이며 앱에 머터리얼 디자인을 적용하게 해줍니다. 또한 MyHomePage는 main.dart 파일에 선언된 사용자 정의(개발자가 작성한)위젯입니다.
정리하면 MyApp에서는 머터리얼 디자인을 적용하려고 MaterialApp을 사용했고 구체적인 화면은 MyHomePager 위젯에서 구성했습니다.
MyHomePage 클래스 알아보기
MyHomePage 위젯 클래스는 StatefulWidget을 상속받아 작성되었습니다. StatefulWidget은 위젯의 화면 구성과 위젯에 출력되는 데이터 등을 별도의 State 클래스에 지정하는데, 예제에서는 _MyHomePageState가 State 클래스입니다. StatefulWidget 클래스가 실행되면 createState() 함수가 자동으로 호출되며 이 함수에서 StatefulWidget을 위한 State 클래스의 객체를 반환합니다.
State를 상속받은 _MyHomePageState 클래스의 build() 함수가 자동으로 호출되면서 이 함수에 구현한 위젯이 화면에 출력됩니다. Scaffold는 appBar, body, floatingActionButton 등으로 화면의 구성 요소를 묶어 주는 위젯입니다. AppBar는 화면 위쪽의 타이틀 바를 나타내고 body는 화면 중간에 Text 위젯으로 문자열을 출력합니다. 그리고 FloatingActionButton으로 화면 오른쪽 아래에 둥근 버튼을 표시합니다.
결국 main() -> MyApp -> MyHomePage -> _MyHomePageState 순서로 실행되었으며 화면을 구성하는 대부분은 _MyHomePageState의 build() 함수에 작성되었습니다.
이제 main.dart 파일의 실행 흐름을 대략 이해할 수 있겠죠? 클래스들을 왜 이렇게 복잡하게 구성하는지, StatelessWidget과 StatefulWidget의 차이점은 무엇인지, State는 어떤 역할을 하는지 등 아직 궁금한 게 많을 것입니다. 앞으로 차근차근 살펴보겠습니다.
'Flutter' 카테고리의 다른 글
컬렉션 타입 - List, Set, Map (0) | 2024.11.11 |
---|---|
var와 dynamic 타입 (0) | 2024.11.11 |
상수 변수 - const, final (0) | 2024.11.11 |
데이터 타입 (0) | 2024.11.11 |
다트 언어란? (1) | 2024.11.11 |