본문 바로가기

안드로이드/Flutter

Flutter 프로젝트 구조와 앱 구조

플러터 프로젝트 폴더 구조

 

프로젝트를 만들면 이 안에 프로젝트 파일들이 자동으로 생성됩니다. 샘플 앱이 함께 생성 되기 때문에 아무것도 하지 않아도 앱이 하나 만들어진겁니다.

 

ios: iOS 빌드시에 필요한 파일들과 코드들이 생성됩니다.

android: Android 빌드시에 필요한 파일들과 코드들이 생성됩니다.

lib: 스켈레톤 앱의 코드가 들어있으며, 이후의 코드 구현은 거의 모두 이 폴더 내에서 합니다.

pubspec.yaml: 플러터 프로젝트의 중심 같은 파일로, 앱 이름, 버전, 빌드, 의존성 (dependencies), 리소스 (이미지, 폰트 파일 등) 등이 모두 등록되어 있는 파일입니다.

 

 

플러터 앱 구조

 

다음은 플러터 프로젝트 생성시 샘플 앱 코드를 나눠봤습니다.

 

 

위 세덩어리는 사실상 거의 수정하지 않는 부분입니다. 그중 아래쪽 두 덩어리인 MyHomePage와 _MyhomePageState는 샘플 앱의 화면을 나타내는 코드입니다. 모든 코드는 사실상 상태클래스를 참조받고 있는 _MyhomePageState에 작성합니다.

 

먼저 import 부분을 살펴봅시다.

import 'package:flutter/material.dart'; 패키지에는 머티리얼 디자인 위젯들이 포함되어 있습니다. 필수적으로 임포트해야 하는 패키지라고 볼 수 있습니다. 필요에 따라서 ios 쿠퍼티노 패키지를 import 할 수도 있겠습니다.

 

StatelessWidget 클래스

 

StatelessWidget 클래스는 클래스 이름 그대로 상태가 없는 위젯을 정의하는데 사용됩니다. 상태를 가지지 않는 위젯을 구성하는 기본 클래스입니다. 여기서 상태를 가지지 않는다는 것은 한 번 그려진 후 다시 그리지 않는 경우이며, 이러한 클래스는 프로퍼티로 변수를 가지지 않습니다. (상태가 없기 때문) 상수는 가질 수 있습니다.

 

build 메서드가 반환하는 MaterialApp은 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Welcome to Flutter',
theme:ThemeData(primarySwatch:Colors.blue,
     home: Scaffold( ··· );
      ),
    );
  }
}

MaterialApp은 위젯은 Material design의 기본 골격을 쉽게 추가할 수 있는 위젯인데 child로 Scaffold 위젯을 추가할 수 있습니다. Flutter 앱내의 모든 것들은 위젯으로 구성됩니다. 간단한 텍스트부터 버튼 그리고 스크린 레이아웃까지 전부 위젯이고 _계층적인 순서_를 가지고 배열합니다. Scaffold (스캐폴드)는 기본적인 Material design 구조를 잡아주는 뼈대라고 보면 됩니다. (출처 : https://duzi077.tistory.com/298 [개발하는 두더지])

 

title은 말 그대로 제목을 나타냅니다. theme는 테마를 지정합니다. home에 작성하는 위젯이 실제 이 앱이 표시하는 위젯이 됩니다. 플러터에서 이름이 있는 인수는 클래스의 프로퍼티에 값을 할당하는 것이며, 그것은 클래스의 속성을 의미합니다.

 

Stateful 클래스

 

상태가 있는 위젯을 정의할 때는 Stateful 클래스를 사용합니다. statefulwidget은 위젯의 생명주기동안 값이 변할 수 있는 위젯입니다. 구현하기 위해서는 반드시 State 인스턴스를 생성하는 StatefulWidget 클래스를 생성해야 합니다. StatefulWidget 자체는 값이 변하지 않지만 내부의 State 클래스가 생명주기동안 값이 변합니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class MyHomePage extends StatefulWidget {
  
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
 
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
 
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
 
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ···,
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

다음은 플루터 스켈레톤 앱으로 카운터 기능을 가지고 있습니다.

 

여기서 setState() 메서드는 전달된 익명 함수를 실행한 후 화면을 다시 그리게 하는 build() 메서드를 다시 실행되는 역할을 합니다.  setState() 메서드는 상속 받고 있는 State 클래스가 제공하는 메서드입니다.

정리하면 MyHomePage 클래스는 StatefulWiget의 서브 클래스이며 상태를 가질 수 있습니다. 그 상태는 StatefulWidget의 createState() 메서드로 상태 인스턴스를 반환 받을 수 있습니다. 그리고 그 상태는 State 클래스의 서브 클래스로 정의합니다. 여기서 변경 가능한 상태는 _counter 변수 입니다. 이 값이 변경될 때마다 화면을 다시 그리면서 동적인 화면을 가진 앱이 됩니다.

 

머터리얼 앱의 기본 형태

 

 

다음으로는 Stateful 위젯의 생명주기에 대해 알아보겠습니다.