NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    기타 Flutter - 플러터를 이용해서 스마트폰 앱 만들기. (Android, iOS)

    페이지 정보

    본문

    안녕하세요. 엔지엠소프트웨어입니다. 이전 시간에 플러터 개발 환경을 구성했는데요. 아직 Flutter 개발 환경을 갖추지 않으신 분들은 아래 링크를 참조하세요.

    [ 안드로이드, 아이폰 앱 개발 - 플러터 개발 환경 구축하기 ]

     

    개발 환경을 만들었으면, 아래 글을 참고하셔서 플러터 프로젝트도 생성 해보세요.

    [ 플러터 스마트폰 앱 프로젝트 만들기 ]

     

    첫 Flutter 앱을 만드는 방법을 알아볼건데요. 아무래도 개발자 또는 개발 언어를 공부하시는 분들은 이 글이 쉽게 느껴질겁니다. 하지만, 처음 프로그래밍 개발에 입문하시거나 1인 개발자로 안드로이드와 아이폰 그리고, 윈도우에서 서비스하고 싶은 분들도 유용한 자료가 될겁니다. 처음부터 너무 깊게 학습하려고 하지 말고 여유를 가지고 하나씩 따라 해보세요. 최소 3개월에서 6개월 정도면 원하는 서비스를 만들 수 있을거예요^^; 참고로, Dart 경험이나 모바일, 웹프로그래밍 경험이 없어도 크게 문제되지 않게 자세하게 작성하도록 하겠습니다.

    WgCINFv.jpg

     

     

    저처럼 1인 개발자 또는 스타트업 회사를 위해 이름을 생성해서 제안하는 간단한 모바일 앱을 구현할겁니다. 이 내용은 구글 및 플러터 공식 사이트에 있는 내용을 초보자도 쉽게 이해할 수 있도록 좀 더 자세하게 기술한 내용입니다. 대부분 개발자를 대상으로 작성된 글이다보니 처음 사업을 기획하시는 비개발자분들이 쉽게 따라하고 학습할 수 있도록 작성하겠습니다. 이 학습을 따라하면 사용자가 이름을 선택하거나 선택을 취소할 수 있고, 가장 좋은 이름을 저장할 수 있습니다. 코드는 Lazy하게 이름을 생성합니다. "Lazy"는 흔하게 접해왔던 기술인데요. 대표적으로 유튜브와 인스타그램을 생각하시면 쉽습니다. 스크롤할 때마다 새로운 목록을 가져오는 방식입니다.

     

    학습 내용

    • iOS와 Android 그리고 웹에서 자연스럽게 보이는 Flutter 앱을 작성하는 방법.
    • Flutter 앱의 기본 구조 이해.
    • 패키지를 찾고 패키지를 사용하여 기능을 확장하는 방법.
    • 더 빠른 개발 사이클을 위한 Hot Reload(HR) 사용.
    • Stateful 위젯을 구현하는 방법.
    • Lazy하게 로드하는 무한 리스트를 만드는 방법.

     

    사용 도구

    • 컴퓨터에 연결되어 있는 개발자 모드로 설정된 실제 기기 (안드로이드폰 또는 아이폰)
    • iOS 시뮬레이터
    • Android 에뮬레이터
    • 윈도우의 웹브라우저 (크롬, 엣지등등...)

     

    비주얼 스튜디오 코드를 실행하세요. 이미 프로젝트를 만든 분들은 Dart 코드가 있는 lib/main.dart 파일이 보일겁니다.

    soRzXQf.png

     

     

    화면 중앙에 Hello World를 표시하기 위해 코드를 아래와 같이 작성 해주세요. 기존 코드는 모두 지우고요^^

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Welcome to Flutter',
          home: Scaffold(
            appBar: AppBar(
              title: Text('Welcome to Flutter'),
            ),
            body: Center(
              child: Text('Hello World'),
            ),
          ),
        );
      }
    }

     

    우리는 이미 안드로이드 에뮬레이터를 하나 만들었습니다. 그래서, VSCode의 우측 하단에 안드로이드 에뮬레이터가 표시됩니다. iOS도 윈도우에서 실행할 수 있지만, xcode가 설치되어 있는 도커 이미지 또는 가상화 프로그램이 필요합니다. 아니면~ 맥북이 있어야겠죠? 이 부분은 나중에 도커 이미지를 다룰때 자세하게 알아보도록 하고, 오늘은 안드로이드 기반으로 진행하도록 하겠습니다.

    CRPvgn1.png

     

     

    에뮬레이터를 실행하면 안드로이드 폰이 하나 표시됩니다. 처음 기기를 실행할 때 로딩이 오래걸릴 수 있습니다. 가상 장치에서 에뮬레이팅하는 방식이라서 이 부분은 어쩔 수 없긴합니다. 하지만, 이후 빠른 업데이트를 위해 hot reload를 사용할 수 있습니다. 앱이 실행중일 때 IDE에서 저장하면 hot reload를 수행합니다. 아래 그림처럼 main 메소드에서 Run 또는 Debug를 클릭해보세요.

    jnPp3bF.png

     

     

    화면 가운데 "Hello World"가 표시되었습니다.

    0Q1QdUJ.png

     

     

    가장 기본이 되는 앱을 하나 만들었습니다. 물론, 아직 아무런 기능도 없습니다. 머터리얼은 모바일 및 웹에서 표준으로 사용되는 시각 디자인 언어입니다. 플러터는 다양한 머터리얼 위젯을 제공합니다. 매인(main) 메소드는 화살표 표기법을 사용합니다. 한줄 함수 또는 메소드 화살표 표기법을 사용하세요. 참고로, 시각 디자인 언어인 머터리얼은 화면 구성에 대한 내용을 스캐폴드(Scaffold) 해줍니다. 스크린을 구성하는 app bar, title, body, align등등... 속성을 기본으로 제공합니다.

     

    앞서 설명했듯이 이 앱은 1인 기업 또는 스타트업 이름을 자동으로 생성하는 서비스를 제공합니다. 따라서, 가장 많이 사용되는 영어 단어 수천개와 몇가지 유틸리티 기능이 포함되어 있는 오픈소스 패키지인 english_words를 이용할겁니다. 다른 오픈 소스 패키지와 마찬가지로 [ https://pub.dev/ ]에서 찾을 수 있습니다. Flutter 앱에서 의존성 및 어셋 관리는 pubspec 파일이 담당합니다. pubspec.yaml의 의존성 목록에 english_words를 추가하세요.

    tqyYrRJ.png

     

     

    Ctrl+S를 누르면 하단의 출력창에 패키지를 가져온것을 확인할 수 있습니다. 정상적으로 패키지를 가져오면 pubspec.lock 파일도 같이 생성됩니다. 어쩌면, 이미 생성되어 있을지도 모릅니다. 이 파일에는 프로젝트로 가져온 모든 패키지 목록과 버전 정보를 포함하고 있습니다. 만약, 패키지 가져오기가 실패하면 pubspec.lock 파일을 삭제하고 다시 실행하세요.

    o4IsmSo.png

     

     

    lib/main.dart에서 패키지를 가져오세요. 대부분의 언어가 라이브러리 또는 모듈 및 패키지를 가져올 때 import를 사용합니다. using을 사용하는 언어도 있습니다.

    import 'package:flutter/material.dart';
    import 'package:english_words/english_words.dart';

     

    대부분의 IDE가 import를 입력할 때 추가할만한 라이브러리를 자동으로 추천해줍니다. 선택해서 사용하면 되는데요. 요즘처럼 IDE의 성능이 막강한 시대에는 누구나 쉽게 개발할 수 있다는 장점이 있습니다. 예전에는 외워서 사용했어야 했는데 말이죠^^; 마지막으로 "Hello World" 대신 English words를 사용해서 텍스트를 생성 해볼께요.

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        final wordPair = WordPair.random(); // <-- 추가
        return MaterialApp(
          title: 'Welcome to Flutter',
          home: Scaffold(
            appBar: AppBar(
              title: Text('Welcome to Flutter'),
            ),
            body: Center(
              child: Text(wordPair.asPascalCase), // <-- 수정

     

    참고로, PascalCase(Upper camel case라고도 함)는 문자열에서 맨 처음 단어를 포함한 모든 단어의 첫번째 글자가 대문자로 시작하는 형식을 말합니다. 그래서, "uppercamelcase"가 "UpperCamelCase"가 됩니다. 이 방식은 프로그래머들에게 익숙한데요. 보통, 클래스나 인터페이스의 네이밍 룰이기 때문입니다. 핫 리로드 버튼을 클릭 해볼까요?

    OgzTXSE.png

     

     

    핫리로드를 클릭하고, 안드로이드 에뮬레이터를 보면 텍스트가 변경된걸 확인할 수 있습니다. 핫 리로드를 클릭할 때마다 혹은 프로젝트를 저장할 때마다 랜덤하게 선택된 다른 단어들을 볼 수 있습니다. MateerialApp이 랜더링 될 때마다 혹은 Flutter Inspector에서 플랫폼을 전환할 때마다 실행되는 build 메서드 안에서 단어를 생성하기 때문입니다. 이 내용은 매우 중요하니~ 외워두셔야 합니다.

    2wSiv4h.png

     

     

    목록으로 표시하기 위해 Stateful 위젯을 하나 추가합니다. 아래 코드를 main.dart 아래에 추가하세요. RandomWords로 지정된 제네릭은 State 클래스를 사용하고 있습니다. 대부분의 앱 로직과 상태는 여기서 유지됩니다. 이 내용을 좀 더 쉽게 이해하려면 웹의 상태 관리에 대한 이해가 먼저 필요합니다. 우선은 그냥 넘어갑시다. RandomWords 위젯에서 상태를 보관한다는 것만 알아두면 됩니다.

    class RandomWords extends StatefulWidget {
      @override
      RandomWordsState createState() => RandomWordsState();
    }
    
    class RandomWordsState extends State<RandomWords> {
      @override
      Widget build(BuildContext context) {
        final wordPair = WordPair.random();
        return Text(wordPair.asPascalCase);
      }
    }

     

    MyApp 클래스에서 아래 내용으로 변경하세요. 추가 되었던 "final wordPair = WordPair.random();" 코드는 삭제 합니다.

            body: Center(
              child: RandomWords(),

     

    마지막으로 무한 스크롤되는 ListView를 만들어줍시다. RandomWordsState를 확장하여 단어 목록을 생성하고 표시합니다. ListView 위젯 안에 표시되는 목록이 사용자가 스크롤할 때마다 무한하게 늘어납니다. 일반적으로 유튜브나 인스타그램에서 다음 목록을 계속 가져와서 표시합니다. ListView의 builder 팩토리 생성자를 사용하면 필요에 따라 Lazy한 방식으로 목록을 만들 수 있습니다. 제안된 단어를 저장하기 위한 변수를 2개 추가해줍니다.

    class RandomWordsState extends State<RandomWords> {
      final _suggestions = <WordPair>[];
      final _biggerFont = const TextStyle(fontSize: 18.0);

     

    _biggerFont는 표시되는 글자를 키우기 위한 텍스트 스타일을 담는 변수입니다. 참고로, _suggestions와 _biggerFont 변수는 앞에 언더바(_)가 붙어 있습니다. 이 변수들은 private이라는 의미입니다. OOP 언어 특성에 대한 설명이 좀 필요한데요. 이 부분도 다음에 자세하게 알아보도록 하고 일단 넘어가도록 합니다. 언더바가 붙으면 프라이빗이 적용된다는것만 외워두세요^^

     

    ListView 클래스는 builder 속성인 itemBuilder를 제공합니다. 이름에서 알 수 있듯이 이 안에서 각각의 항목을 만들어줍니다. 이 팩토리 필더는 익명 함수 형태의 콜백 함수를 받습니다. 두 인자가 함수에 전달되는데요. BuildContext와 반복 변수입니다. 반복 변수 i는 0부터 시작되고 함수가 호출될 때마다 자동으로 1씩 증가합니다. ListTitle에 제안된 모든 단어에 대해 2번씩, 그리고 Divider에 1번씩 증가합니다. 이 로직을 사용하면 스크롤 할 때마다 목록이 무한하게 증가할 수 있게 됩니다.

    Widget _buildSuggestions() {
      return ListView.builder(
          padding: const EdgeInsets.all(16.0),
          itemBuilder: /*1*/ (context, i) {
            if (i.isOdd) return Divider(); /*2*/
    
            final index = i ~/ 2; /*3*/
            if (index >= _suggestions.length) {
              _suggestions.addAll(generateWordPairs().take(10)); /*4*/
            }
            return _buildRow(_suggestions[index]);
          });
    }

     

    목록에서 각각의 아이템을 생성하기 위한 _buildRow 메소드를 추가하세요.

    Widget _buildRow(WordPair pair) {
      return ListTile(
        title: Text(
          pair.asPascalCase,
          style: _biggerFont,
        ),
      );
    }

     

    MyApp 클래스를 아래와 같이 변경 해줍니다. title을 변경하고 홈(home)을 RandomWords로 변경하세요.

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Startup Name Generator',
          home: RandomWords(),
        );
      }
    }

     

    리스타트 해볼까요? 여러분들도 아래 그림처럼 잘 표시가 될겁니다. 2개의 단어를 조합해서 스타트업 회사 이름을 만드는 간단한 앱을 만들어 봤습니다. 웹에 대한 기본적인 지식과 OOP 언어적인 특성들에 대한 이해가 있으면 이 글에서 간혹(?) 나오는 전문적인 단어들을 이해하는데 어렵지는 않을겁니다. 그런데, 처음 접하시는 분들은 도대체가 어떤 의미로 말하는건지 혼란스러울겁니다. 프로그래밍을 배운다는 것은 러닝커브(Learning Curve)가 존재하고, 이 학습 곡선은 계단식으로 이해하게 됩니다. 서서히 하나씩 이해하는게 아닌 일단 외우고, 어느정도 파악이 되고 눈으로 확인하고 이것저것 바꿔가면서 동작이 이해될 때 한단계 내공이 상승합니다.

    opZUSnT.png

     

     

    참고로, 에뮬레이터 또는 시뮬레이터를 구글 크롬이나 엣지로 변경하고 다시 실행 해보세요. 아래와 같이 웹브라우저에서도 확인할 수 있습니다.

    OMwemmE.png

     

     

    계단식 학습의 단점은 이해하지 못하고 넘어가는 것들에 대해 불안하고, 왜 이렇게 되는지 감이 안오기 때문에 대부분의 사람들이 프로그래밍 또는 코딩을 어려워하고 쉽게 포기하게 만든다는 것입니다. 포기하지 않고 계속 하다보면 어느순간 엉켜있는 실타레가 풀리는것처럼 그동안 해왔던 코딩이 이해되고 머리속이 맑아지는 느낌을 받게 됩니다. 이게 생각보다 중독성이 크고 성취감을 느끼게 해줍니다. 그래서, 포기하지 않고 한달이고 두달이고 노력하다보면 어느새 개발자의 길로 들어서게 될겁니다. 제가 학원 강사를 하던 시절을 떠올려 보면 대부분은 1달안에 포기합니다^^; 그리고, 3개월이 되면 30프로정도만 남고요. 교육이 끝나는 6개월정도 되면 10프로정도가 남아서 취업을 준비합니다.

     

    한두달만에 자신의 가능성을 보지 말고, 최소 1년은 해봐야 개발의 즐거움과 성취감 그리고, 달콤한 과실을 딸 수 있습니다. 1단계 교육을 완료한것에 축하드리고, 다음에는 이 내용을 좀 더 발전시켜서 클릭 가능한 "좋아요" 아이콘을 추가하겠습니다. 가장 좋아하는 단어를 보관하는 새로운 화면과 경로를 추가하고 그 화면으로 이동하는 내비게이션 기능을 구현 해봅시다.

    2부에서 만들 앱

     

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.