Flutter 2.0


Fuchsai에서 동작하는 크로스 플랫폼 프레임워크

  • Cross platform 모바일, 웹, 데스크톱 UI SDK이다. 하나의 코드로 안드로이드, 아이폰, 맥북, 윈도우즈 pc, 웹용 앱을 만들 수 있다!
  • Dart를 사용한다.
  • 네이티스 CPU 머신 코드로 직접 컴파일을 지원한다.
  • UI를 자체 렌더 엔진 스키아로 렌더링하여 성능이 뛰어나다.
  • 구글의 Material 테마 디자인과 Ripple 애니메이션을 사용가능하다.
  • 반대로 안드로이드에서 애플의 Cupertino 테마를 적용가능하다. ~~~와웅~~~
  • 각 OS 플랫폼의 네이티브 UI 구성 요소로 변환하지 않고, 플러터의 그래픽 렌더 엔진을 통해 직접 플랫폼 Canvas상에 드로잉하기 때문에 높은 성능과 플랫폼 무관한 디자인을 구현가능하다.
  • React native에 비해 관심을 더 쏟고 있다는 것이 장점


모바일 개발 환경 발전사

  • Kotlin
  • Web View, Web App
  • React Native : JavaScript 사용
  • Flutter

지원 장비

  • Android
  • 아이폰, 맥북, 윈도우즈, 웹

Flutter 설치

  • Flutter download

    • c:/appl/flutter252 폴더로 압축을 풀어서 이동
    • Window 시스템 변수 변수
      • path : c:/appl/flutter252/bin
  • Android Studio Chipmunk, 2021.2.1 Patch 2

    • https://developer.android.com/studio?hl=ko
    • "File > Settings > Plugins" 메뉴에서 Flutter 를 설치 한다.
    • "SDK Manager" 아이콘 선택
      • "File > Settings > Appearance & Behavior > System Settings > Android SDK" 메뉴와 동일
      • SDK Platforms 탭
        • Android API 32
          • Android SDK Platform 32
        • Android 12.0 (S)
          • Android SDK Platform 31
          • Sources for Android 31
      • SDK Tools 탭
        • Android SDK Build-Tools 33-rc2
          • 32.0.0
          • 31.0.0
        • Android SDK Command-line Tools (latest)
          • Android SDK Command-line Tools (latest)
        • Android Emulator
        • Android Emulator Hypervisor Driver for AMD Processors (installer)
        • Android SDK Platform-Tools
        • Android SDK Tools
        • Intel x86 Emulator Acceleator (HAXM installer)
      • SDK Update Sites 탭
    • "DeviceManager" 아이콘 선택
      • "Create device" 버튼 선택
      • "Pixel 4 XL" 선택
      • "API 32"와 "S" 다운로드
  • Xcode for iPhone in MAC

#--- PowerShell을 관리자 모드로 실행 한다.
cd  c:/appl/flutter252
./flutter_console.bat
cd  c:/work/OBCon_Mobile

flutter  --version
flutter  doctor                         #--- Flutter 환경을 점검
#--- 표시 사항을 확인하여 필요한 것을 추가로 설치/구성 한다.
#--- ANDROID_HOME: C:\Users\User\AppData\Local\Android\Sdk
flutter  doctor  --android-licenses


VSCode에서 사용 설정

  • Marketplace에서 Flutter 설치
  • "보기 > 명령 팔레트 ..." 메뉴에서 "Flutter: Launch Emulator" 실행
    • "Pixel 4 XL" 선택
    • "실행 또는 디버그" 아이콘을 선택하여 앱 실행

Flutter Project 생성

  • Android Studio 프로그램을 실행 한다.

  • "New Flutter Project" 버튼을 선택 한다.

    • Flutter SDK path : c:/appl/flutter252
    • Project name : obcon_mobile
    • Project locatin : c:/work/OBCon_Mobile
    • Project type : Application
    • Organization : biz.obcon.flutter
    • Android language : Kotlin
    • iOS language : Swift
    • Platform : Android, iOS

Folder 구조

  • .dart_tool/ : Dart Tool 설정 폴더
  • .idea/ : VSC (Visual Studio Code) 설정 폴더
  • android/ : Android 코드 생성용 폴더
  • assets/ : 자원 폴더
  • build/ : 컴파일과 빌드용 폴더
  • ios/ : iOS 코드 생성용 폴더
  • lib/ : 프로그램 소스 코드
    • include/
    • modules/
      • homes/
      • users/
    • main.dart : 어플리케이션의 메인 프로그램
    • OBConApp.dart
  • test/ : 테스트 프로그램 소스 코드
  • upgrades/ : 업그레이드 관리용으로 만든 폴더
  • zzstudy/ : 스터리용으로 만든 폴더
  • pubspec.yaml : 어플리케이션 설정
  • pubspec.lock
  • .flutter-plugins
  • .flutter-plugins-dependencies
  • .metadata
  • .packages : 패키지 정의
  • analysis_options.yaml
  • obcon_mobile.iml

Application 구조

  • MyApp
    • MyHomePage
      • State : _MyHomePageState
        • build() : 화면을 구성

Widget


flutter/material.dart

안드로이드용 테마 적용

  • 구조

    • MaterialApp (Stateful)
    • Scaffold (Stateful)
      • AppBar (Stateful)
        • SliverAppBar
          • SliverFillRemaining
          • SliverList
      • body
      • BottomNavigationBar
        • BottomNavigationBarItem
      • BottomSheet
      • FloatingActionButton (Stateless) : 플로팅 버튼
      • Drawer : 드로우 메뉴
  • 화면

    • StatelessWidget

    • StatefulWidget

      • createState() : 상태 객체 생성
      • State
        • widget 변수로 StatefulWidget 참조
        • initState() : 초기화
        • didChangeDependencies()
          • initState() 함수 뒤에 호출됨
        • build() : 화면 생성
        • setState() : 상태 업데이트
          • 이후 didUpdateWidget() > build() > updateShouldNotify() > didUpdateWidget() 함수가 호출됨
        • didUpdateWidget()
          • InheritedWidget에 의존하고 있는 경우에만 호출됨
        • dispose() : 삭제
    • InheritedWidget : 하위 위젯에서 접속할 수 있는 위젯

      • 사례 : Theme, MediaQuery, Scaffold
      • updateShouldNotify()
      • .of(context). 문법 사용
  • 레이아웃

    • Container : 하나의 위젯을 포함
    • Row : 수평 방향 정렬
    • Column : 수직 방향 정렬
    • Stack : 여러 위젯을 겹쳐서 표시
    • Table
      • TableColumnWidth
      • TableCellVerticalAlignment
      • TableRow
        • TableCell
  • 모양과 정렬

    • Center
    • Padding
    • Align : 정렬
    • Expanded : 위젯의 높이를 비율로 지정
    • SizedBoz : 위젯의 크기를 지정
    • Card : 카드 형태의 위젯
  • 기초

    • ListView (Stateless) < CustomScrollView

      • ListTitle (Stateless) : 항목
      • AboutListTitle
      • StreamBuilder : 비동기 데이터로 위젯을 만들어 반환
    • SingleChildScrollView : 상하 스크롤 구현

      • Column
      • ListBody
    • Divider

    • GridView : 여러 열을 표시

      • SliverGrid
        • SliverChildBuilderDelegate
        • SliverGridDelegateWithEixedCrossAxisCount
    • PageView : 좌우로 슬라이드하는 페이지

    • DefaultTabController

      • TabBar

        • Tab
      • TabBarView

  • 출력

    • Text (Stateless)
    • Image (Stateful)
      • assets/image/
      • pubspec.yaml
    • Icon (Stateless)
    • CicleAvatar (Stateless)
    • Opacity : 투명도 부여
    • 버튼
      • RaisedButton (Stateless)
      • FlatButton
      • DropdownButton
      • IconButton
      • FloatingActionButton (Stateless)
  • 입력

    • Form

      • TextFormField (Stateful)

      • DropdownButtonFormField

      • CountryDropdownField

      • FormField

        • checkbox
      • FormState

        • save()
        • reset()
        • validate()
      • GlobalKey

    • TextField

      • InputDecoration
    • CheckBox

    • Switch

    • Radio

      • RadioListTitle
    • AlertDialog

    • DatePicker

    • TimePicker

  • 이벤트

    • GestureDetector : Widget에 제스처 기능을 추가

      • Dismissible
    • InkWell

    • RouteObserver

      • NavigatorObserver
      • RouteAware
    • BuildTransitions

      • SlideTransition
      • SizeTransition
      • RotationTransition
      • AlignTransition
  • 기타

    • 애니메이션
      • Hero (Stateful)
      • AnimatedContainer
      • AnimationController
      • CustomPainter
        • Paint

flutter/cupertino.dart

iOS용 테마 적용

  • CupertinoNavigationBar
  • CupertinoSwitch
  • CupertinoButton
  • CupertinoAlertDialog
  • CupertinoPicker

BLoC

  • Business Logic Component
  • StreamController와 ~.of(context) 기능을 사용하여 구현함
    • ~.stream.listen()
    • ~.add()
    • StreamController.broadcast()
  • StreamBuilder 사용


JSON

import 'package:json_annotation/json_annotation.dart';

// part 'todo.g.dart';

@JsonSerializable()
class Todo {
  final field01;
  
  Todo(this.field01);
  
  factory Todo.fromJson(Map json) => _$TodoFromJson(json);
  
  Map toJson => _$TodoToJson(this);
}


import 'dart:convert';

String context = '{ ~ }';
Map jsonObj = json.decode();

jsonObj = Map{
  'name01': 'value01',
  'name01': 100
};
context = json.encode(jsonObj);

유용한 코드

//--- aaa 위젯의 상위 위젯중에서 ppp를 가진 위젯의 ppp를 반환 한다. 
aaa.of(context).ppp
  
//--- StreamController
//---     StreamController.broadcast() : 전체 전파
StreamController _controller = StreamController();
Stream get onEvent => _controller.stream;

//---     Listen하고 있다가 실행할 함수 지정
onEvent.listen((NewEvent event) => print(event));

//---     Event 호출
_controller.add(NewEvent());

//--- Future
Future funcFuture() async {
  try {
    return true;
  } catch (err) {
    print('Error: $err')
    return false;
  }
}

funcFuture()
    .then((bool returnValue) => {})
    .catchError((err) => {});

bool returnValue = await funcFuture();

//--- 일정 시간 후에 함수 실행
Timer(const Duration(seconds: 2), () => goHomePage(context));

Future.delayed(2 * 1000).then(() => goHomePage(context));

//--- 화면 넓이 반환
final width = MediaQuery.of(context).size.width;

프로그램 샘플

import 'package:flutter/material.dart';

void main() => runApp(OBConApp());

class OBConApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'OBCon Mobile',
            theme: ThemeData(
                primarySwatch: Colors.blue
            ),
            home: OBConHomePage(title: '홈페이지')
        );
    }
}

class OBConHomePage extends StatefulWidget {
    final String title;
    
    OBConHomePage({Key: key, this.title}) : super(key: key);
    
    State createState() => _OBConState();
}

class _OBConState extends State {
    @override
    void initState() {
        super.initState();
    }
    
    @override
    Widget build(BuildContext context) {
        
    }
    
    @override
    void setState(VoidCallback fn) {
        
    }
}

Column(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
        Text('~'),
        Text(
            '~',
            style: TextStyle(
                color: Colors.black,
                fontSize: 20.0,         //--- dp
                background: Paint()
                    ..color = Color(0xFFDCEDC8)
                    ..style = PaintingStyle.fill,
                fontWeight: FontWeight.bold
            )
        )
        Image.asset('assets/~.jpg')
    ]
)

참고 문헌

최종 수정일: 2023-02-21 18:07:01

이전글 :
다음글 :
상단 menu
arrow_back_ios
arrow_forward_ios