티스토리 뷰
재즐보프님의 Flutter강의를 보고 배운 내용을 정리하는 게시물입니다.
www.youtube.com/watch?v=Yt-DjG5b4iA&list=PLnIaYcDMsScxP2Nl8pEbmI__wkF0YVu0a
우선 플러터 설치와 플러터에 대한 설명은 강의에서 직접 확인하세요! 저는 플러터로 어플리케이션을 개발하는 부분만 정리하겠습니다!
먼저 플러터로 기본 파일을 만들었을 때 구성되는 main.dart 파일에 대하여 알아봅시다.
void main() {
runApp(MyApp());
}
첫 번째로 main함수가 있는데 이름에서도 알 수 있다시피 이것은 main function의 역할을 하고 이 내부에서 'MyApp이라고 선언된 것을 실행시킨다' 라고 생각하면 될 것 같습니다.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.blueGrey),
home: MyHomePage(title: 'Flutter Demo Home Page')
);
}
}
앞에서 본 실행시키는 MyApp에 해당하는 부분입니다.
사실상 이 부분에 대해서 큰 설명은 없지만 개인적으로 궁금해서 좀 찾아봤습니다.
1. Widget?
먼저 Flutter 공식 문서에는 다음과 같이 서술되어 있습니다.
Flutter widgets are built using a modern framework that takes inspiration from React. The central idea is that you build your UI out of widgets. Widgets describe what their view should look like given their current configuration and state. When a widget’s state changes, the widget rebuilds its description, which the framework diffs against the previous description in order to determine the minimal changes needed in the underlying render tree to transition from one state to the next.
사실 플러터 입문자인 저에게는 여기서 가장 눈에 띄는 부분은
The central idea is that you build your UI out of widgets.
When a widget’s state changes, the widget rebuilds its description, which the framework diffs against the previous description in order to determine the minimal changes needed in the underlying render tree to transition from one state to the next.
이렇게 되는 것 같습니다.
정의 자체를 이해하는 것보다는 그냥 위젯은 'GUI 모든 장치' 정도로만 생각하면 될 것 같습니다.
예를 들어, 메모 앱을 만들게 되면 '메모 추가' 버튼을 넣을 텐데 이것 또한 위젯, '메모 앱' 이라는 상단 타이틀을 넣어주면 이것 또한 위젯이 되는 것이라고 이해했습니다. (또한, 조금 읽어보면 이 위젯들이 모여서 위젯 트리를 구성하는 형태입니다.)
이 코드에서는 MyApp이라는 Class 내에서 MaterialApp을 반환하는 Widget을 하나 만든 셈이다. 그런데 실행시켜보면 알 수 있듯이 이 부분이 Flutter로 만든 앱의 이름, 테마, 내용을 대강 정하는 곳이다. 그래서 저는 '이 어플 자체를 관통하는 위젯을 하나 만들었다~' 라고 생각했습니다.
2. BuildContext?
위에서 말했듯이 Flutter에서 위젯은 거의 모든 GUI 요소를 뜻합니다.
그리고 이 많은 위젯들이 모여서 계층 구조를 이루고 이에 따라 우리가 만들어낸 앱 화면이 나타나는 셈입니다.
그런데 계층 구조를 이룰 때 자식 계층에 있는 위젯이 부모 계층에 있는 위젯과 상호 동작하려면 어떡해야 하는가?
이것을 하게 해주는 것이 바로 'BuildContext' 입니다.
'어떤 특정 위젯이 Build 되는 Context' 라고 재즐보프님이 강의에서 말씀해주셨는데 이것들을 종합해보면,
'Flutter 앱은 위젯으로 구성되며 이 위젯들은 계층 구조를 이루며 계층 간에 상호 동작을 BuildContext를 통해 이루어진다'
이 정도로 생각하면 될 것 같습니다.
3. MaterialApp?
Flutter 공식 문서에는 다음과 같이 서술되어 있습니다.
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 and GridPaper.
Material Design을 가능하게 해주는 Class인 셈입니다.
이 때, Material Design이란 위키백과에 따르면 다음과 같습니다.
머티리얼 디자인(Material Design, 코드명: Quantum Paper)[1]이란 플랫 디자인의 장점을 살리면서도 빛에 따른 종이의 그림자 효과를 이용하여 입체감을 살리는 디자인 방식을 말한다. 2014년 구글이 안드로이드 스마트폰에 적용하면서 널리 퍼지기 시작했다. 플랫 디자인과 마찬가지로 최소한의 요소만을 사용하여 대상의 본질을 표현하는 디자인 기법인 미니멀리즘(minimalism)을 추구한다.
이와 같은 디자인을 손쉽게 할 수 있는 것이 바로 'MaterialApp' 클래스였던 것입니다.
그리고 공식 문서에 따르면 이는 유용한 Widget들을 많이 포함하고 있어 유용하게 사용할 수 있다~ 라는 식으로 설명되어 있는 걸 보니, Flutter를 이용하여 앱 개발을 할 때 대부분 사용하는 것 같습니다.
4. Title?
이 또한 Flutter 공식 문서를 찾아보겠습니다.
The primary widget displayed in the app bar.
Typically a Text widget that contains a description of the current contents of the app.
제일 단순한 것 같은데, 가장 최근에 사용한 앱을 들어가보면 뜨는 이름을 말하는 것 같습니다.
5. Theme?
말 그대로 우리가 만들어낼 Flutter 앱의 전반적인 Theme를 나타내는 것입니다.
처음에는 이걸 왜 굳이 해주나,, 싶었는데 전반적인 Theme라는 것이 글꼴, 색상을 통일시켜준다는 것이(설정에 따라 특정 부분에서만 글꼴, 색상을 통일시켜주기도 함) 상당히 편리하다는 걸 최근에 프로젝트를 하면서 깨달았습니다.
어떠한 프로그램을 만들 때는 여러 사람이 함께하기 마련인데, 만드는 사람마다 자신이 생각하는 색깔, 글꼴을 쓰면 통합할 때 상당히 골치아픈데.. 이를 막기 위해 Theme를 정하고 개발을 시작하면 너무나도 편리해지는 겁니다.
그리고 Theme에 들어가 있는 'primarySwatch'라는 놈은 Flutter 공식 문서를 찾아도 잘 나오지 않아 구글링을 했습니다.
기본 바탕이 되는 색 정도인 것 같습니다.
그리고 스택오버플로우의 답변에서도 알 수 있듯이, primarySwatch는 color가 아니라 MaterialColor를 의미한다고 하네요.
6. Home?
MyApp Class 하나 뜯어보기 되게 어렵군요.. 마지막으로 home입니다.
앱을 빌드만 해보더라도 바로 알아볼 수 있겠지만 앱 내부에 띄우는 페이지를 연결하는 놈입니다.
'앱을 실행시켰을 때 처음 뜨는 화면을 MyHomePage라는 Class로 연결하겠다' 정도의 의미라고 보시면 될 것 같습니다. 그리고 이 때, 처음 뜨는 화면에 넘기는 Title을 뒤에 정해준 것으로 보면 됩니다.
그렇다면 기본적으로 띄우는 화면인 MyHomePage를 구현해야합니다.
class MyHomePage extends StatefulWidget {
final String title;
MyHomePage({Key key, this.title}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
먼저 아까 MyApp Class에서 title로 넘겨주었던 title을 받아옵니다. (이것은 나중에 _MyHomePageState에서 다시 나올 것임)
여기서도 처음 보는 것은 'StatefulWidget' 입니다.
기본적으로 extend하는 Widget은 크게 두 가지로 나뉘어집니다.
StatefulWidget, StatelessWidget
여기서 전자인 'StatefulWidget'은 상태를 변경할 수 있는 Widget을 의미합니다.
반대로 후자인 'StatelessWidget'은 상태를 변경할 수 없는 Widget을 의미합니다.
그러니까 우리가 만들려고 하는 앱의 현재 페이지가 동적이냐 정적이냐에 따라 선택하여 사용하면 될 것 같습니다.
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title),),
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text('$_counter', style: Theme.of(context).textTheme.display1,)
],
)
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: "Increment",
child: Icon(Icons.add),
),
);
}
void _incrementCounter() {
setState(() {
_counter++;
if (_counter > 15) {
_counter = 0;
}
});
}
}
마지막으로 _MyHomePageState입니다.
(전체적인 코드를 확인해보면 알 수 있다시피 계속해서 class를 중첩해서 호출하는 형태입니다. 그래서 실제로는 MyApp Class에 Build할 때 모든 내용을 넣어서 한 번에 만들어낼 수도 있습니다.)
여기서 return 해주는 Scaffold는 Material Design의 기본 구조를 쉽게 잡을 수 있게 해주는 위젯입니다.
appBar라든가, body라든가, floatingActionButton이라든가 등등을 쉽게 추가하여 넣는 위젯이라고 보면 되겠습니다.
appBar: AppBar(title: Text(widget.title),),
appBar는 기본 페이지 상단에 app의 이름을 띄워주는 Bar이면 이에 쓰여지는 이름을 MyApp에서 넘겨준 title로 잡기 위해 widget.title을 넣어줍니다.
원래는 this 포인터를 사용하겠지만 Flutter 앱 개발을 할 때는 this 대신 widget으로 관리한다고 보시면 되겠습니다.
body: Center(
child: Column(mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('You have pushed the button this many times:'),
Text('$_counter', style: Theme.of(context).textTheme.display1,)
],
)
),
body에 Center를 붙혀 가운데 정렬을 기본으로 하고,
child에 Column을 넣어주어 가운데 정렬된 Column을 사용하게 됩니다.
Column이라 함은, 위젯을 추가하고 배열할 수 있는 공간인데 Row도 따로 존재합니다.
Flutter 공식 문서에서는 다음과 같은 사진을 예시로 들고 있습니다.
(출처: flutter.dev/docs/development/ui/layout)
사진으로 보니까 확실히 이해되는 것 같습니다. 가운데 정렬된 Column을 이용한 것이니 페이지의 행 중에 가운데에 위치하는 걸 만든 거겠죠?
그리고 그 Column에는 2개의 Text가 Children으로 들어갑니다.
Text는 쓰여진 것이 그대로 들어간다는 것을 바로 알 수 있을테고, 중요한 것은 달러 표시($)입니다.
Flutter에서 변수를 만들고 그 변수를 집어 넣을 때는 '$변수이름' 의 형식을 사용합니다.
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: "Increment",
child: Icon(Icons.add),
),
onPressed : 클릭했을 때 실행시키는 함수
tooltip : 터치가 아니라 꾹 누르면 뜨는 메시지
Icon : floatingActionButton 내에 넣을 Icon
안드로이드 스튜디오로 FloatingActionButton을 구현해본 사람은 알 수 있듯이 상당히 편하게 진행 중입니다. (처음 FloatingActionButton을 만들 때의 그 공포는 아직도 기억납니다.. dependency 추가하고 오류나고 수정하고 고치고 Icon 넣었는데 너무 작아서 수정하고 등등..)
void _incrementCounter() {
setState(() {
_counter++;
if (_counter > 15) {
_counter = 0;
}
});
}
이건 뭐 설명할 부분이 하나도 없는 일반 함수입니다. (if절은 제가 그냥 인위적으로 넣은 것이니 무시하셔도 됩니다.)
React를 할 때와 유사한 것은 변경사항을 전달할 때 setState를 이용한다는 것입니다.
이것만 기억하면 될 것 같습니다.
Dart 언어를 처음 접하다보니 아직은 미숙한 점도 있고 Flutter에 대한 어려움도 있긴 하지만 계속해서 이렇게 정리해나갈 예정입니다.
강의를 보고 따라하는 시간보다 정리하고 복습하는 시간이 더 오래 걸리는 것 같은데 복습도 확실히 되고 내부 조직도 제대로 알 수 있어서 좋은 것 같습니다ㅎㅎ 👏
'Programming 📱 > Flutter' 카테고리의 다른 글
[재즐보프님 Flutter 강의] 플러터(Flutter)로 메모앱을 만들며(2) (0) | 2021.01.30 |
---|---|
[재즐보프님 Flutter 강의] 플러터(Flutter)로 메모앱을 만들며(1) (0) | 2021.01.29 |