[ Flutter ] 유데미 x 글또 : 기획에서 개발까지 한방에 도전하는 플러터

2024. 4. 12. 04:49Mobile/Flutter

오랜만에 모바일과 관련된 글을 쓰는 것 같아요. 처음 플러터를 배웠던 것도 작년 12월 겨울 유데미 코딩 페스티벌이었는데요. 거기서 홍드로이드님의 크리스마스 카드를 플러터로 만들어서 브라우저로 크리스마스 뮤직 플레이어를 만들어서 실행해봤어요. 

좋은 기회에 유데미에서 글또에 강의를 제공해주셨는데, 플러터에 원래 관심이 있었던지라, 제공되는 강의 리스트 중에 플러터를 보자마자 신청했어요. 

 

제목이 길어져서 위의 제목처럼 썼지만 정확한 강의명은

기획부터 개발까지 한방에 도전하는 플러터(Flutter) 수익형 기초 앱 개발 입니다! 

유데미에서 제공한 강의를 듣고 작성한 후기입니다.

 

플러터를 크게 보자면, C, C++, Java 와도 유사하다고 하더라고요. 코드의 빌드 형태를 보면 선언형 프로그래밍인 SwiftUI 와도 많이 닮아있어요. 플러터의 강점은 iOS, Android 모바일 운영체제 둘다 사용할 수 있다는 것이에요. 그래서 관심을 가진 것도 있어요.

우선 강의소개와 일부 실습의 코드와 설명을 하기 앞서 플러터의 기본 문법과 프로그램 세팅을 간략하게 얘기해보려고 해요. 

(저는 플러터 왕초보니까요...😊..)

 

문법 연습같은 걸 해보려면, dartpad.dev 사이트에서 가능해요. 

 

속성 기본 문법

플러터에서 Main 함수는 프로그램 시작 지점을 가지고 있는 함수에요. print 이든, 데이터 타입, 변수든 끝에는 ; 으로 마무리 해줘요. 변수와 자료형은 다른 프로그래밍 언어와 비슷하고요. 

// main 함수 안 데이터 타입들 
void main() {
  String name = 'Nat';
  print(name);
  
  int age = 100;
  print(age);
  
  var address = 'California'; 
  // dart 에서 지원하는 문법 
  //변수값에 대한 타입 추론을 하게됨.
  print(address);
}

// bool 타입
void main() {
  bool isChecked = false;
  print(!isChecked);
}

String 타입은 앞이 대문자고, int (정수형) 은 소문자네요. 언어 컨벤션이니 이렇게 써줘야죠 ㅎㅎ

bool 타입도 앞에 타입을 먼저 명시하고 변수명을 적어줘요. 

 

여기서 잠깐! dynamic 타입 이라는 것도 있는데요.

어느 프로그래밍 언어 문법이든 다른 타입끼리 값을 할당해줄 수가 없어요. 플러터도 마찬가지고요. 여기서 Dynamic type 을 쓰면 

타입 상관없이 할당이 가능해요.

-> 많이 남용하면 혼동이 오거나 부작용이 발생할 수 있으니, 꼭 필요한 때에 쓰는게 좋구요. 

void main() {
  String name = 'Nat';
  name = '냇';
  print(name);
  
  name = 100; // String 타입에 int 타입 값을 할당할 수 없음.
  print(name);

  dynamic car = 'ferrari';
  car = 10;
  print(car);
}

 

Flutter 개발 환경 구축 방법 

검색어로 'Flutter SDK 설치 및 환경변수 설정 방법' 을 쳐봐요. 저는 macOS 환경에서 작업을 함으로 Flutter 공식 사이트 내에서도 macOS 에 맞는 튜토리얼을 찾아서 설치했어요.

https://docs.flutter.dev/get-started/install/macos/mobile-ios

 

Start building Flutter iOS apps on macOS

Configure your system to develop Flutter mobile apps on macOS and iOS.

docs.flutter.dev

IDE 같은 경우는 vscode 를 써도 된다지만, Android Studio 를 보통 많이 쓰고, 여기서 설정을 하는게 편할 거 같아서 Android Studio 를 설치했어요.

1. Android Studio 를 설치하고 나서 plugin 으로 Dart 와 Flutter 도 설치해줘야 하구요.

2. Setting < Appearance & Behavior > Languages .. > Android SDK > SDK Tools 에서

3. Android SDK Command-line Tools 를 눌러 적용하고 OK 해주고 나서,

      flutter 가 준비될 수 있게 아래 명령어를 terminal 에서 입력해줬어요.

flutter doctor --android-licenses

 

4. 환경변수 등록

terminal 

touch ~/.zshrc

open ~/.zshrc

 

설치 경로 -> Flutter 폴더 경로 끝은 bin 으로 끝낸다.

export PATH="$PATH:[flutter folder path]/bin"

 

5. 다 세팅이 잘 되었는지, 다시 flutter doctor 입력해본다.

이슈가 없다면 저런 신호들이 떠요! 

 

Flutter 프로젝트 만들기!

1. Android Studio > New Flutter Project  만들기 누르면 이 화면이 뜨고 Next 버튼을 눌러요. 

2. 프로젝트 명, 위치 설정, 프로젝트에 대한 자세한 설명, Organization 은 Xcode 에서의 Bundle Name 과 같다고 보면 돼요. 이 프로젝트에 대한 서술같은 거요. ㅎㅎ Android 기기의 언어는 Kotlin 혹은 Java, iOS 는 Swift 를 대체적으로 쓰니까 Swift 에 체크 되어 있으면 돼요. 

홍드로이드 - 명함 앱 만들기 실습!! 

에 대해 설명을 하기 전에 pubspec.yaml 에 대해 빠르게 짚고 넘어갈게요! 

pubspec.yaml 

- 의존성 라이브러리들을 추가할 수 있어요.
- 버전세팅 
- 패키지 검색: pub.dev

 

패키지 추가 방법( 설치하고 싶은 오픈소스)

flutter pub add [package_name]
flutter pub add image_compare_slider

위의 사진처럼 버전세팅, 오픈소스와 관련된 코드, 그리고 이미지 assets 경로를 설정할 때도 여기서 해줘요.

이미지 에셋 폴더 생성 후 경로 설정 

flutter:
  assets:
    - assets/
  uses-material-design: true

 

프론트단에서는 package.json 과 같은 역할을 하는 녀석이라고 해요. 

 

강의 내용을 다 공개하진 않을 거구요 ㅎㅎ

제가 진행된 곳까지 어떤 식으로 UI 를 짜는지, Swift 와의 다른 점을 비교해가면 강의를 봤던 것 같아요. 에뮬레이터로 디바이스를 런 빌드 했구요. 

 

명함 앱 구성
1. Splash 뷰(launch Screen) - 앱이 시작될 때 잠깐 보이는 앱의 화면 - 앱의 로고나 소개 같은 느낌  
2. main 화면 (main_screen)

 

lib 폴더 내 main 파일 안 필요없는 주석은 다 지워줍시다! 

1. splash_screen, main_screen 파일명들을 생성

플러터의 파일명 짓는 컨벤션은 lowercase 에 _ 를 붙여 써요. 

class SplashScreen extends StatelessWidget {
  const ({super.key});

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}
// stl -> 자동으로 상태 관련 위젯이 뜬다.
  1. stl 누르면 자동완성으로 StatelessWidget 이 생성된다.
  2. SplashScreen 커서 살아 있는 상태에서 enter 치고 StatelessWidget
  3. → ⌥(opt) + ⏎(enter): import 라이브러리 material dart 자동으로 넣어준다.

opt + enter(macOS기준) 자동 Import가&nbsp; 됩니다.

main.dart ( main_screen, splash_screen 을 import ) 

main.dart 파일에서

option + Enter 해서 만든 파일명을 import 적용 시켜줌

 

2.  Splash View 설정 

import 'package:flutter/material.dart';

/// 시작화면
class SplashScreen extends StatelessWidget {
  const SplashScreen({super.key});

  @override
  Widget build(BuildContext context) {
    Future.delayed(Duration(seconds: 2), () {
      Navigator.pushReplacementNamed(context, '/main');
    },);

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Image.asset(
              'assets/mymimoticon.png',
              width: 180,
              height: 180,
            ),
            Container(
              margin: EdgeInsets.only(top: 32),
              child: Text('Mobile Developer',
                style: TextStyle(
                  fontSize: 36,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
  • material 의 속성? 중 하나인 Scaffold() 를 사용해줘요. 

NOTE

정렬 맞추기!

Swift - Auto layout 에서의 centerX, centerY 설정해서 화면의 가운데 오는 것처럼,
flutter 에서도 

mainAxisAlignment: MainAxisAlignment.center 

이렇게 지정해주면 센터로 오게 돼요.

 

  • 스플래시 애니메이션 후 main_screen 으로 화면 이동 
 Future.delayed(Duration(seconds: 2), () {
    Navigator.pushReplacementNamed(context, '/main');
  },);

 

3. main_screen 

앱 상단에 위치하는 appBar 설정

1. build 안에 Scaffold 생성 → appBar 만들어주기

class _MainScreenState extends State<MainScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(appBar: AppBar(),)
  }
}

 

 

2. image , 이름, 정보 등 - 둥근 형태의 widget 이미지 넣기 

→ body 를 ScrollView 로 감쌀 예정

SingleChildScrollView 내 → Child → Column → children

NOTE - 여기서 잠깐!
위젯이란 UI 구성하는 기본단위 입니다.
뷰를 나타내는 dart class 고, UI 가 어떻게 나타날지 보여지는 전체적인 틀이라고 생각하면 될 것 같아요.

 

class _MainScreenState extends State<MainScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Icon(
          Icons.accessibility_new,
          color: Colors.black,
          size: 32,
        ),
        backgroundColor: Colors.white,
        title: Text(
          '도전하는 모바일개발자 Nat 입니다.',
          style: TextStyle(
            fontSize: 14,
            color: Colors.black,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [

          ],
        ),
      ),
    );
  }
}

Image 의 크기 조절 → w/h 바로 쓰지 않고 Container 로 감싸줘요. 참고로 code 자동 정렬은 괄호마다 , 를 넣어줘야 예쁘게 정렬돼요.

 

2. 이미지 내 배경과 borderRadius 적용

class _MainScreenState extends State<MainScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: Icon(
          Icons.accessibility_new,
          color: Colors.black,
          size: 32,
        ),
        backgroundColor: Colors.white,
        title: Text(
          '도전하는 모바일개발자 Nat 입니다.',
          style: TextStyle(
            fontSize: 14,
            color: Colors.black,
            fontWeight: FontWeight.bold,
          ),
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: [
            Container(
              margin: EdgeInsets.all(16),
              padding: EdgeInsets.all(8),
              width: double.infinity,
              height: 160,
              decoration: BoxDecoration(
                  color: Colors.tealAccent,
                  borderRadius: BorderRadius.circular(10)
              ),

              child: ClipRRect(
                borderRadius: BorderRadius.circular(10),
                child: Image.asset(
                  'assets/iOSnat_1.png',
                  fit: BoxFit.fitHeight,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

 

Row 를 Container 로 감싸고(opt + Enter _ macOS 기준 코드스니펫)

Container 여러 요소로 복사해서

다른 요소들로 바꿔줍니다. → 이름, 메일, 취미, 언어, 직업

 

Container >

margin: EdgeInsets.symmetric(vertical: 8, horizontal: 16) → 항목과 관련정보 마진 주는 것!

child: Row >

Container : Text(항목) - width 150 으로

Text(관련 정보)

3. TextField 설정

TextField

라인 설정(height 길어짐)

decoration → border radius, border color

  • textField 수정가능하게 상위에 변수 선언
  • TextEditingController introduceController = TextEditingController();

그럼 언제든지 자기소개에 대한 내용을 편집할 수 있어요. Swift 에서의 UITextField 같은거죠. Flutter 는 TextEditingController 를 설정해주지만, Swift 에서는 UITextField 의 부차적인 기능을 쓰려면 UITextFieldDelegate 같은 걸 써줘야죠. 

 

강의 1강을 더 들으면 명함 앱 세션은 끝나지만 여기까지 소개해드리려고 해요. 이런식으로 코드를 짜면 완성되는 화면은 아래와 같아요.

자기소개는 텍스트필드라서 키보드로 언제든 수정 가능해요.

 

 

플러터를 가르치시는 분들은 많지만, 홍드로이드님을 유데미 코딩페스티벌에서 속성으로 들었는데요. 촉박하고 2,3시간 되는 강의, 많은 사람들과 라이브 코딩을 진행했음에도 친절하게 모든 사람들의 눈높이에서 최대한 강의를 진행해주셨던 기억이 나요. 

그래서 명함 앱 세션뿐만 아니라 왕초보의 입장에서 부담없이 다 듣고 차후에 플러터로 꼭 앱 배포하는 것이 목표에요! 

 

마지막으로 알고가면 좋을 단축키를 몰아서 정리해봐요~~ 

단축키 shortcuts
- 자동정렬 -> cmd + option + L 
- 어떤 요소를 감싸는것  ex. column, container, 등
     -> opt + enter
- code block 접기: cmd + .
- parameter 리스트 보기: cmd + p

 

 

대체적으로 부담없이 편하게 강의를 들을 수 있었어요. 홍드로이드님 오픈카톡방을 들어가게 된다면, 모르는 것도 바로바로 알려주시는 편이더라고요. 2024년 4월 23일 화요일에는 무료 플러터 강의 세션도 있다하니 참 기대가 돼요.(들어보고 싶어서 신청 완..😅)
제 베이스는 사실 iOS 네이티브지만, 그래서 iOS 와 Flutter 와 비교하는 것도 흥미롭고요. Android Studio에서 쓸 수 있는 기능들도 좋았어요. 나중에 다른 os 디바이스에서도 작업할 수 있다는게 매력적인 것같아요.  

 

유데미 [앱 개발 템플릿 무료 제공] 기획부터 개발까지 한방에 도전하는 플러터(Flutter) 수익형 기초 앱 개발  을 듣고 정리한 개략적인 내용과 후기입니다.


macOS 환경에서 flutter 를 세팅하고 프로젝트를 만든 내용입니다. 

틀린 내용이나 문제 시 피드백, 댓글 남겨주세요~

(지속적으로 내용 업데이트 및 수정 있을 수 있습니다~ )