Flutter 시작하기 : Hello Flutter!

윤뿔소·2023년 5월 22일
0

Dart / Flutter

목록 보기
10/18

전편에 이어서 다 했다면

위 사진처럼 잘 뜰 것이다. 핫로딩이 되는 모습을 볼 수 있다.

이제 Hello Flutter를 출력해보자.

시작하기

만들었던 Flutter 초기 단계에서 main() 빼고 지우고, 새로 시작하자.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

그러면 위처럼 남을 것이다.

Widget

일단 runApp()이란 아래 사진과 같다.

runApp은 Widget이라는 것을 argument로 받는다. 여기서 Widget은 리액트의 컴포넌트라고 생각하면 된다.

리액트가 CDD 방식으로 컴포넌트를 조합해서 만든다면, 플러터는 위젯이라는 레고 블럭을 가지고 만든다. 쉽지않는가? 플러터 공식문서나 다른 플러터 커뮤니티에서 만든 위젯을 또 가져올 수도 있다. 리액트의 재사용성을 활용한 셈.

즉, 위젯은 사용자 인터페이스를 구성하는 기본적인 빌딩 블록이다. 위젯은 UI 요소의 불변성을 나타내며, 위젯 트리를 구성하기 위해 조합하여 사용된다. 위젯은 화면에 그려지고 레이아웃에 배치되며, 사용자와의 상호 작용을 처리하기 위해 이벤트를 처리할 수 있다.

여기서 Stateful과 Stateless한 위젯으로 나뉘게 된다.

Stateless 위젯 (StatelessWidget)

상태를 가지지 않고 정적으로 변하지 않는 위젯이다. 한 번 생성된 후에는 내부 상태가 변경되지 않으며, 외부에서 전달된 속성에 따라 UI를 렌더링한다. 단순하게 무언가를 화면에 띄워주기만 하는 역할.
예를 들어, 레이블 또는 아이콘과 같은 단순한 UI 요소는 StatelessWidget으로 구현될 수 있다.

Stateful 위젯 (StatefulWidget)

상태를 가지고 동적으로 변할 수 있는 위젯이다. 사용자의 상호 작용이나 시간에 따른 변화에 따라 내부 상태가 변경되고 UI가 업데이트된다.
예를 들어, 사용자 입력에 따라 상태가 변경되는 폼이나 인터랙티브한 위젯은 StatefulWidget으로 구현될 수 있다.


또한, 위젯은 계층적으로 구성될 수 있고, 상위 위젯과 하위 위젯 사이의 관계를 형성한다. 이 계층 구조를 사용하여 복잡한 UI를 구성할 수 있다.

루트 위젯인 class App 만들기

즉, 우리가 화면 상 보이는 요소를 렌더링을 하려면 그냥 클래스가 아닌 위젯을 받은 클래스를 만들어야한다는 것이다.

이제 차이를 알았으니 상태가 없는 정적 클래스 App을 만들어보자.

그랬더니 이렇게 나오네? StatelessWidget.build 메소드를 구현하지 않았다는 것이다.
즉, StatelessWidget은 추상클래스이며 우리는 이 것을 상속 받았기에 꼭꼭 bulid 메소드를 구현해야한다는 것이다.

자주 쓰는 메소드이기에 VSC가 자동완성으로 알아서 해준다.

...
class App extends StatelessWidget {
  
  Widget build(BuildContext context) {
    // TODO: implement build
    throw UnimplementedError();
  }
}
  1. build가 정의됨.
  2. 어노테이션 @override이 사용
    • StatelessWidgetbuild를 우선하게끔 재정의
abstract class StatelessWidget extends Widget {
  const StatelessWidget({ super.key });
  
  StatelessElement createElement() => StatelessElement(this);
  
  Widget build(BuildContext context);
}

위 코드는 StatelessWidget가 정의된 코드이다. build가 있기 때문에 상속받은 App도 만들어야한다.

Root Widget

이제 됐고, 우리가 쓴 클래스 App이 이것은 애플리케이션의 시작점이 되는 Root 위젯이 됐다. 이 위젯이 뭘 return해서 화면에 렌더링 할 것이냐가 중요하다.

또한 루트 위젯은 2가지 선택을 리턴해야하는데

  1. Material 디자인
    구글이 개발한 UI 디자인 스타일로, 그림자, 반응형 레이아웃, 아이콘, 터치 피드백 등을 포함. Material 디자인을 사용하려면 MaterialApp 위젯을 루트 위젯으로 반환. 이 경우, MaterialApp 위젯은 Material 디자인의 테마 및 위젯을 애플리케이션에 적용.
  2. Cupertino 디자인
    Apple의 iOS 디자인 스타일로, iOS 플랫폼에 익숙한 사용자들에게 친숙한 느낌을 주는 디자인을 제공. Cupertino 디자인을 사용하려면 CupertinoApp 위젯을 루트 위젯으로 반환. CupertinoApp 위젯은 Cupertino 디자인의 테마 및 위젯을 애플리케이션에 적용.

즉, 구글이냐 애플이냐의 어떤 Family 스타일로 사용할 건지 플러터에게 말해주는 것이다.

class App extends StatelessWidget {
  
  Widget build(BuildContext context) {
    // 1. 
    return MaterialApp();
    // 2.
    return CupertinoApp();
  }
}

이렇게 말이다. 중요한 점이 우리만의 UI 디자인을 가지고 싶다고 해도 시작점을 정해주고, 재료를 줘야한다는 것이다. 스타팅 포인트를 지정해주는 것과 같다.

플러터는 구글에서 만들었기에 당연히 Material 디자인이 훨씬 이쁘고 많이 쓰인다! 활용도도 높기에 구글 느낌을 빼고 커스텀도 보다 쉽게 가능하다.

나도 Material로 정했다.

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp();
  }
}

이제 MaterialApp()의 소속된 멤버에 맞춰서 개발해야한다.

class MaterialApp extends StatefulWidget {
  /// Creates a MaterialApp.
  const MaterialApp({
    super.key,
    this.navigatorKey,
    this.scaffoldMessengerKey,
    // home이 중요!
    this.home,
    Map<String, WidgetBuilder> this.routes = const <String, WidgetBuilder>{},
    this.initialRoute,
    this.onGenerateRoute,
    this.onGenerateInitialRoutes,
    this.onUnknownRoute,
    List<NavigatorObserver> this.navigatorObservers = const <NavigatorObserver>[],
    this.builder,
    this.title = '',
    this.onGenerateTitle,
    this.color,
    this.theme,
    this.darkTheme,
    this.highContrastTheme,
    ...

겁나 많다. 그 중 home을 가져와서 출력을 해볼 것이다.

class App extends StatelessWidget {
  
  Widget build(BuildContext context) {
    
    return MaterialApp(
      home: ,
    );
  }
}

위 같이 써주니 아래와 같이 에러가 뜬다.

home은 위젯이고 위젯이니 또 그 안에 무안 갈 넣어줘야한다.

class App extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Text('Hello Flutter!'),
    );
    // return CupertinoApp();
  }
}

이렇게 Text를 넣어줬다! 결과를 보자.

겁나 못생겼다. 그 이유는 또다른 플러터 규칙인 Scaffold가 필수이고, 지금은 없기 때문이다.

Scaffold

Scaffold는 건축 비계를 뜻하는데 기초 건설을 의미한다.

위 사진이 건축 비계, Scaffold다.

한마디로 Scaffold화면의 구성 및 구조에 관한 것들을 가지고 있는 아주 멋진 위젯이다.
건축처럼 플러터에서 모바일 앱 화면에 보여지는 모든 요소, 위젯은 Scaffold가 필수다.

Scaffold는 클래스로서 애플리케이션의 기본적인 구조와 일반적인 머티리얼 디자인 요소를 제공하며, 앱의 상단 바, 하단 탐색 바, 드로어어, 플로팅 액션 버튼 등을 구성할 수 있다.

구성 요소

  1. AppBar: AppBar는 상단 바를 나타내는 위젯으로, 타이틀, 액션 버튼, 백 버튼 등을 포함.
  2. Body: Body는 애플리케이션의 주요 콘텐츠를 표시하는 위젯. 일반적으로 ListView, Column, Container 등과 같은 다른 레이아웃 위젯과 함께 사용.
  3. BottomNavigationBar: BottomNavigationBar는 하단 탐색 바를 나타내는 위젯으로, 여러 개의 탭을 가질 수 있음. 사용자가 탭을 선택할 때마다 해당 탭의 콘텐츠가 표시.
  4. Drawer: Drawer는 앱의 왼쪽에서 오른쪽으로 슬라이드되는 사이드 메뉴를 나타내는 위젯. 주로 앱의 설정이나 추가 메뉴 옵션을 표시하는 데 사용.
  5. FloatingActionButton: FloatingActionButton은 주로 하단 탐색 바 위에 위치하며, 빠른 작업을 수행하기 위한 원형 아이콘 버튼을 나타냄.

Scaffold 위젯은 이러한 구성 요소들을 조합하여 애플리케이션의 기본적인 레이아웃을 구성한다. 이를 통해 일반적인 앱 구조와 사용자 인터페이스 요소를 쉽게 구현할 수 있다.

그러면 이제 추가해보자!

class App extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('My Flutter'),
        ),
        body: Center(
          child: Text('Hello Flutter!'),
        ),
      ),
    );
  }
}

벌써 괄호 줄세우기로 어질어질 한데 일단 보자.

  1. 속성 home 위젯에 Scaffold 클래스이자 위젯 추가
  2. 속성 appBar라는 위젯을 불러오고, AppBar라는 클래스(위젯) 추가
  3. AppBar 요소인 title에 Text 추가
  4. 안 요소인 body 속성 추가
  5. 가운데 정렬 해주는 Center 위젯 추가
  6. 그 자식을 지정하기 위해 child 속성 추가 및 Text 추가

이렇게 해서 결과물은!?

짠! 이뻐졌다! 이렇게 간단하고 쉽게 만들 수 있다.
그 안에 어떤 요소가 있고 어떻게 사용해야하는지는 전체 암기를 안해도 되지만 자주 쓰이는 것들은 숙지해놓자.

요약

  1. 플러터 프로젝트 만들기 : flutter create toolfix
  2. 프로젝트 코드 지우고 우리만의 클래스 App 선언
  3. App을 루트 위젯으로 만들기 위해 StatelessWidget 상속
  4. 상속과 동시에 build 메소드를 만들어야하기에 build 자동완성 작성
  5. App 위젯이 루트 위젯이기 때문에 Family 스타일 return : MaterialApp()
  6. MaterialApp()의 멤버를 살펴보고 속성 home을 작성해 렌더링
  7. home 작성 뒤 화면에 보여줄 때 필수인 Scaffold 작성
  8. Scaffold의 하위 속성들을 작성하여 appBarbody 작성
    • AppBar : appBar 속성에 작성, 상단바를 만들 수 있는 위젯
      • title : 상단바의 제목
    • Center : 메인 콘텐츠를 작성하는 곳인 body에 작성, 가운데 정렬 가능한 위젯
      • child : Center에 포함될 위젯 작성
    • Text : String 등을 받는 텍스트 위젯

처음으로 플러터에서 출력을 해봤는데 ㄹㅇ 파면 팔수록 미친 겁나 많은 위젯들이 나온다. OOP의 정수 플러터 답다.
심지어 만든 개발자가 변태인지 위젯, 클래스들을 넣고 마우스 오버를 하면 넣을 수 있는 속성들은 물론이고 설명을 일일이 다 해놨다. 이래서 플러터의 DX가 최고 수준이라고 하는구나 생각했다. 다양한 걸 활용하니 재밌어지겠다 ㅎㅎ

또 알아둬야할 것이 우리는 위젯이니, 위젯의 속성을 가져오느니 이런 얘기들을 했지만 핵심은 전부 클래스를 사용하는 것이다.
저렇게 사용하는 것이 Named 클래스를 사용하는 것과 똑같기에 겁먹지말고 그 클래스들의 Constructure를 잘 사용해보자.

profile
코뿔소처럼 저돌적으로

5개의 댓글

comment-user-thumbnail
2023년 5월 22일

고생하셨네요 플러터 dart 어렵네요 ㅠ

답글 달기
comment-user-thumbnail
2023년 5월 28일

진짜 많은걸 하시는군요 !!

답글 달기
comment-user-thumbnail
2023년 5월 28일

어렵네요... 화이팅입니닷

답글 달기
comment-user-thumbnail
2023년 5월 28일

플러터까지 @.@ ... 생소한 내용이라 어려운데 그래도 정리가 야무지셔서 잘봤습니다 ㅎㅎ

답글 달기
comment-user-thumbnail
2023년 5월 28일

위젯이라는 개념이 재밌네요!!

답글 달기