SlideShare a Scribd company logo
처음 시작하는 Flutter
GDG Songdo / Flutter Songdo
@양수장
Getting started with Flutter
Bio
GDG Songdo Organizer (2020~ )
Flutter Songdo Organizer (2022 ~ )
Tech Lead @bluefrog (2020 ~ )
- Android
- Flutter
- Back-end + DevOps
I’m an App Developer.
yangsterchief@duck.com
https://github.com/yangster-chief
https://www.linkedin.com/in/sujang-yang
GDG 인천 & 송도의 새로운 행사
소식은 카톡 오픈채팅방에서 :D
GDG 인천, 송도로 검색! 혹은 QR로 :)
카카오톡 오픈 채팅
https://open.kakao.com/o/gTplSH6
OO으로 처음 시작하는 Flutter
[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter
[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter
Flutter 왜 해야해요?
Flutter 어떻게 시작 해야해요?
라는 질문 대신에
개인 앱 프로젝트로 처음 시작하는
Flutter
Android, iOS, Web
개인 앱 프로젝트로 처음 시작하는 Flutter
선언형 UI 구조에 익숙하면 바로 시작할 수 있음.
Dart의 문법 구조는 다른언어와 매우 유사함 ( Javascript, Java)
Android - Jetpack Compose UI
iOS - Swift UI
Web - React.js
[Google I_O Extended Daejeon 2023] 처음 시작하는  Flutter
// Imperative style
b.setColor(red)
b.clearChildren()
ViewC c3 = new
ViewC(...)
b.add(c3)
// Declarative style
return ViewB(
color: red,
child: const ViewC(),
);
var stars = Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star, color: Colors.green[500]),
const Icon(Icons.star, color: Colors.black),
const Icon(Icons.star, color: Colors.black),
],
);
final ratings = Container(
padding: const EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
stars,
const Text(
'170 Reviews',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20,
),
),
],
),
);
One Source Multi Platform
개인 앱 프로젝트로 처음 시작하는 Flutter
하나의 소스코드로 여러개의 플랫폼에서 작동하는 어플리케이션 빌드 가능.
Android, iOS, Web, Linux, Windows, macOS
- Framework
- UI 구성요소 및 위젯
- Engine
- 렌더링 엔진
- Embedder
- 엔진을 구동하기 위한 네이티브
코드
Architectural Layers
Flutter Project Overview
name: flutter_example
...
environment:
sdk: ">=2.17.3 <3.0.0"
dependencies:
flutter:
sdk: flutter
cupertino_icons: "^1.0.2"
device_preview: "^1.1.0"
...
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: "^2.0.1"
...
flutter:
uses-material-design: true
assets:
- assets/icons/
- assets/placeholder/
- assets/images/
...
/pubspec.yaml
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugins.GeneratedPluginRegistrant
class MainActivity: FlutterActivity() {
private val openIntent: String = "openIntentChannel"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
MethodChannel(flutterEngine.dartExecutor, openIntent).setMethodCallHandler(
IndentHandler(activity)
)
}
}
/Android/app/src/main/kotlin/MainActivity.kt
import UIKit
import Flutter
import FirebaseCore
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
private func setupFirebase() {
...
}
}
/ios/Runner/AppDelegate.swift
- One Source Multi Platform
- 선언형 UI
- Dart는 Javascript, Java와 매우 유사함.
- Native의 기능을 극한까지 사용하는 경우 외의 대부분의 앱을 만들 수 있음.
- Flutter 공식문서, Codelabs, Flutter 공식 Youtube 로 시작할 수 있음.
정리
나의 개발 커리어로 처음 시작하는
Flutter
Flutter만 배운 개발자가 취업하는 방법
나의 개발 커리어로 처음 시작하는 Flutter
모바일 APP 개발자로 취업
- 부전공이 하나쯤은 꼭 있어야함. (Android / iOS)
- Web 경험도 플러스 요소가 될 수 있음.
Web 개발자로 취업
- … React.js를 배우는게 빠릅니다.
Flutter만 알아도 되지 않나요?
...
<dict>
...
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
...
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>sms</string>
<string>tel</string>
<string>mailto</string>
</array>
...
<key>NSCameraUsageDescription</key>
<string>카메라에 접근하도록 허용합니다.</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>위치 접근 권한이 필요합니다.</string>
...
</dict>
</plist>
/ios/Runner/Info.plist
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example">
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<queries>
<!-- If your app checks for SMS support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
...
</queries>
<application
android:label="@string/app_name"
android:name="${applicationName}"
android:icon="@mipmap/launcher_icon">
<activity
android:name=".MainActivity"
android:exported="true"
...
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
...
</activity>
...
</application>
</manifest>
/Android/app/src/main/AndroidManifest.xml
// Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974
BUNDLE_IDENTIFIER=com.example
FLUTTER_TARGET=lib/src/config/env/env_develop.dart
DISPLAY_NAME=flutter_example
GOOGLE_SERVICE_INFO_PLIST=Develop/GoogleService-Dev-Info.plist
FIREBASE_APP_ID_FILE=firebase_app_id_file_dev.json
/ios/Flutter/Develop.xcconfig
...
android {
...
defaultConfig {
applicationId "com.example"
minSdkVersion 23
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
dimension "build-type"
}
signingConfigs {
release {
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
}
}
...
flavorDimensions "build-type"
productFlavors {
...
}
}
flutter {
source '../..'
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
/Android/app/build.gradle
Native Development
Platform Channel
- Flutter에서 실행할 수 없는 코드를
네이티브에서 실행
- Method Channel
- Event Channel
Writing custom platform-specific code | Flutter
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class _MyHomePageState extends State<MyHomePage> {
static const platform = MethodChannel('samples.flutter.dev/battery');
// Get battery level.
String _batteryLevel = 'Unknown battery level.';
Future<void> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
}
...
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "samples.flutter.dev/battery"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
// This method is invoked on the main thread.
call, result ->
if (call.method == "getBatteryLevel") {
val batteryLevel = getBatteryLevel()
if (batteryLevel != -1) {
result.success(batteryLevel)
} else {
result.error("UNAVAILABLE", "Battery level not available.", null)
}
} else {
result.notImplemented()
}
}
}
}
/Android/app/src/main/kotlin/MainActivity.kt
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery",
binaryMessenger: controller.binaryMessenger)
batteryChannel.setMethodCallHandler({
[weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in
// This method is invoked on the UI thread.
guard call.method == "getBatteryLevel" else {
result(FlutterMethodNotImplemented)
return
}
self?.receiveBatteryLevel(result: result)
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
/ios/Runner/AppDelegate.swift
Native Development
Packages and Plugins (The Boring Flutter Development Show, Ep. 6)
상태관리 라이브러리
var stars = Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.star, color: Colors.green[500]),
const Icon(Icons.star, color: Colors.black),
const Icon(Icons.star, color: Colors.black),
],
);
final ratings = Container(
padding: const EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
stars,
const Text(
'170 Reviews',
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w800,
fontFamily: 'Roboto',
letterSpacing: 0.5,
fontSize: 20,
),
),
],
),
);
BuildContext
BuildContext?! | Decoding Flutter
- 부전공이 필요함 (Android, iOS, Web)
- Platform Channel, BuildSettings
- Flutter Web은 아직 시기상조
- 상태관리 라이브러리를 배우자
- GetX 외에도 bloc나 provider를 배우자
- BuildContext 개념 필요
정리
팀의 신규 프로젝트로 처음 시작하는
Flutter
Android 2년차 개발자가 Flutter 프로젝트에 투입
팀의 신규 프로젝트로 처음 시작하는
Flutter
대기업 자회사의 Android 개발자로 채용됨
회사의 그룹웨어 및 신규 프로젝트를 개발하는 TF팀
팀 구성
- Android 9년차 팀장
- iOS 2년차 사원
- Android 5년차 사수
이해관계에 맞는 프로젝트 규모 산정
팀의 신규 프로젝트로 처음 시작하는
Flutter
프로젝트 규모에 따라 사용할 수 있는 상태관리 라이브러리가 달라짐. 일반적으로
- bloc : 대규모
- provider : 중, 소규모
- getX : 소규모
무엇보다도 팀원간의 이해와 소통 (컨벤션) 이 중요합니다.
bloc, provider, GetX 비교 분석
[Flutter Festival GDG Songdo] GetX, provider, bloc 패턴 비교 분석 - 유병욱
협업 방식은 팀바팀, 사바사가 국룰입니다. 하지만,
팀의 신규 프로젝트로 처음 시작하는
Flutter
더 나은 협업을 위해서 고려해볼 몇가지
- DI
- Flutter Theme
- Clean Architecture
- CI / CD
Dependency Injection
Flutter Theme
DevFest Songdo 2022 - Flutter Theme 디자이너와 호감작하기
Clean Architecture
[Flutter Festival GDG Songdo] Flutter에 Clean Architecture를 얹어보자 - 양수장
CI / CD
Github Actions를 활용한 Flutter 배포 자동화하기 - 양수장(GDG Songdo) I 모두콘 2022
Tips & Best Practices
[Flutter Festival GDG Songdo] Flutter 상용화 앱 프로젝트 적용기 - 손민재
- 프로젝트 규모 산정이 최우선
- 핵심 기능이 Flutter로 구현 가능한지 여부 확인
- 협업을 위한 기술
- Flutter Theme
- Clean Architecture
- DI
- CI / CD
정리
처음 시작하는 Flutter
yangsterchief@duck.com
https://github.com/yangster-chief
https://www.linkedin.com/in/sujang-yang

More Related Content

PDF
Flutter로 글로벌앱 출시를 위한 꿀팁 - Droidknights2020
PDF
Android와 Flutter 앱 개발의 큰 차이점 5가지
PPTX
1. 개발환경 셋팅
PPTX
GMS 프로젝트 - Flutter
PDF
[Native vs Flutter] Flutter가 몸에 좋은 이유 _ 개발자 건강을 위한 최ᄀ...
PPTX
0. flutter 소개
PDF
[Flutter Meetup In Songdo] 상태관리 올바르게 쓰기
PPTX
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...
Flutter로 글로벌앱 출시를 위한 꿀팁 - Droidknights2020
Android와 Flutter 앱 개발의 큰 차이점 5가지
1. 개발환경 셋팅
GMS 프로젝트 - Flutter
[Native vs Flutter] Flutter가 몸에 좋은 이유 _ 개발자 건강을 위한 최ᄀ...
0. flutter 소개
[Flutter Meetup In Songdo] 상태관리 올바르게 쓰기
2023 GDG Sondo DevFest - Flutter/ Flavor, PlatformChannel, Environment variab...

Similar to [Google I_O Extended Daejeon 2023] 처음 시작하는 Flutter (17)

PDF
Flutter 101 - 2024년 8월 28일 파인디지털 강연 발표자료
PPTX
flutter
PPTX
3. pubspec.yaml 사용법
PPTX
[GDG 대전] Flutter에 Firebase 한스푼 - GDG Flutter Festival
PDF
D2 캠퍼스 세미나 - 학생 개발자에서 신입 개발자로 한단계 업그레이드 하기
PDF
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
PDF
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
PDF
1.Create Project Sunshine - 시온고등학교 안드로이드 스터디
PDF
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
PDF
협업하는 디자이너 - #4 Android
PDF
Flipper 불완전 정복
PPTX
How to implement your dream 20150427
PPTX
모바일 해커톤 사전교육 2일차
PPTX
앱 인벤터 2: 비전공자를 위한 안드로이드 앱 만들기
PPTX
NHNNEXT 고등학생 창의체험 프로그래밍 실습
PPTX
2. widget
PDF
대화면 기기와 폴더블을 위한 앱 개발 (인공지능위크 2023)
Flutter 101 - 2024년 8월 28일 파인디지털 강연 발표자료
flutter
3. pubspec.yaml 사용법
[GDG 대전] Flutter에 Firebase 한스푼 - GDG Flutter Festival
D2 캠퍼스 세미나 - 학생 개발자에서 신입 개발자로 한단계 업그레이드 하기
[2022]Flutter_IO_Extended_Korea_멀티모듈을활용한플러터클린아키텍처_...
[TECHCON 2019: MOBILE - Android]3.안드로이드 개발자 로드맵
1.Create Project Sunshine - 시온고등학교 안드로이드 스터디
[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)
협업하는 디자이너 - #4 Android
Flipper 불완전 정복
How to implement your dream 20150427
모바일 해커톤 사전교육 2일차
앱 인벤터 2: 비전공자를 위한 안드로이드 앱 만들기
NHNNEXT 고등학생 창의체험 프로그래밍 실습
2. widget
대화면 기기와 폴더블을 위한 앱 개발 (인공지능위크 2023)
Ad

[Google I_O Extended Daejeon 2023] 처음 시작하는 Flutter

  • 1. 처음 시작하는 Flutter GDG Songdo / Flutter Songdo @양수장 Getting started with Flutter
  • 2. Bio GDG Songdo Organizer (2020~ ) Flutter Songdo Organizer (2022 ~ ) Tech Lead @bluefrog (2020 ~ ) - Android - Flutter - Back-end + DevOps I’m an App Developer. yangsterchief@duck.com https://github.com/yangster-chief https://www.linkedin.com/in/sujang-yang
  • 3. GDG 인천 & 송도의 새로운 행사 소식은 카톡 오픈채팅방에서 :D GDG 인천, 송도로 검색! 혹은 QR로 :) 카카오톡 오픈 채팅 https://open.kakao.com/o/gTplSH6
  • 7. Flutter 왜 해야해요? Flutter 어떻게 시작 해야해요? 라는 질문 대신에
  • 8. 개인 앱 프로젝트로 처음 시작하는 Flutter
  • 9. Android, iOS, Web 개인 앱 프로젝트로 처음 시작하는 Flutter 선언형 UI 구조에 익숙하면 바로 시작할 수 있음. Dart의 문법 구조는 다른언어와 매우 유사함 ( Javascript, Java) Android - Jetpack Compose UI iOS - Swift UI Web - React.js
  • 12. // Declarative style return ViewB( color: red, child: const ViewC(), );
  • 13. var stars = Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.star, color: Colors.green[500]), const Icon(Icons.star, color: Colors.black), const Icon(Icons.star, color: Colors.black), ], ); final ratings = Container( padding: const EdgeInsets.all(20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ stars, const Text( '170 Reviews', style: TextStyle( color: Colors.black, fontWeight: FontWeight.w800, fontFamily: 'Roboto', letterSpacing: 0.5, fontSize: 20, ), ), ], ), );
  • 14. One Source Multi Platform 개인 앱 프로젝트로 처음 시작하는 Flutter 하나의 소스코드로 여러개의 플랫폼에서 작동하는 어플리케이션 빌드 가능. Android, iOS, Web, Linux, Windows, macOS
  • 15. - Framework - UI 구성요소 및 위젯 - Engine - 렌더링 엔진 - Embedder - 엔진을 구동하기 위한 네이티브 코드 Architectural Layers
  • 17. name: flutter_example ... environment: sdk: ">=2.17.3 <3.0.0" dependencies: flutter: sdk: flutter cupertino_icons: "^1.0.2" device_preview: "^1.1.0" ... dev_dependencies: flutter_test: sdk: flutter flutter_lints: "^2.0.1" ... flutter: uses-material-design: true assets: - assets/icons/ - assets/placeholder/ - assets/images/ ... /pubspec.yaml
  • 18. import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel import io.flutter.plugins.GeneratedPluginRegistrant class MainActivity: FlutterActivity() { private val openIntent: String = "openIntentChannel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine) MethodChannel(flutterEngine.dartExecutor, openIntent).setMethodCallHandler( IndentHandler(activity) ) } } /Android/app/src/main/kotlin/MainActivity.kt
  • 19. import UIKit import Flutter import FirebaseCore @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } private func setupFirebase() { ... } } /ios/Runner/AppDelegate.swift
  • 20. - One Source Multi Platform - 선언형 UI - Dart는 Javascript, Java와 매우 유사함. - Native의 기능을 극한까지 사용하는 경우 외의 대부분의 앱을 만들 수 있음. - Flutter 공식문서, Codelabs, Flutter 공식 Youtube 로 시작할 수 있음. 정리
  • 21. 나의 개발 커리어로 처음 시작하는 Flutter
  • 22. Flutter만 배운 개발자가 취업하는 방법 나의 개발 커리어로 처음 시작하는 Flutter 모바일 APP 개발자로 취업 - 부전공이 하나쯤은 꼭 있어야함. (Android / iOS) - Web 경험도 플러스 요소가 될 수 있음. Web 개발자로 취업 - … React.js를 배우는게 빠릅니다.
  • 25. <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example"> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <queries> <!-- If your app checks for SMS support --> <intent> <action android:name="android.intent.action.VIEW" /> <data android:scheme="sms" /> </intent> ... </queries> <application android:label="@string/app_name" android:name="${applicationName}" android:icon="@mipmap/launcher_icon"> <activity android:name=".MainActivity" android:exported="true" ... android:windowSoftInputMode="adjustResize"> <!-- Specifies an Android theme to apply to this Activity as soon as the Android process has started. This theme is visible to the user while the Flutter UI initializes. After that, this theme continues to determine the Window background behind the Flutter UI. --> ... </activity> ... </application> </manifest> /Android/app/src/main/AndroidManifest.xml
  • 26. // Configuration settings file format documentation can be found at: // https://help.apple.com/xcode/#/dev745c5c974 BUNDLE_IDENTIFIER=com.example FLUTTER_TARGET=lib/src/config/env/env_develop.dart DISPLAY_NAME=flutter_example GOOGLE_SERVICE_INFO_PLIST=Develop/GoogleService-Dev-Info.plist FIREBASE_APP_ID_FILE=firebase_app_id_file_dev.json /ios/Flutter/Develop.xcconfig
  • 27. ... android { ... defaultConfig { applicationId "com.example" minSdkVersion 23 targetSdkVersion flutter.targetSdkVersion versionCode flutterVersionCode.toInteger() versionName flutterVersionName dimension "build-type" } signingConfigs { release { storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] } } ... flavorDimensions "build-type" productFlavors { ... } } flutter { source '../..' } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } /Android/app/build.gradle
  • 28. Native Development Platform Channel - Flutter에서 실행할 수 없는 코드를 네이티브에서 실행 - Method Channel - Event Channel Writing custom platform-specific code | Flutter
  • 29. import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class _MyHomePageState extends State<MyHomePage> { static const platform = MethodChannel('samples.flutter.dev/battery'); // Get battery level. String _batteryLevel = 'Unknown battery level.'; Future<void> _getBatteryLevel() async { String batteryLevel; try { final int result = await platform.invokeMethod('getBatteryLevel'); batteryLevel = 'Battery level at $result % .'; } on PlatformException catch (e) { batteryLevel = "Failed to get battery level: '${e.message}'."; } ...
  • 30. import androidx.annotation.NonNull import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity: FlutterActivity() { private val CHANNEL = "samples.flutter.dev/battery" override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { // This method is invoked on the main thread. call, result -> if (call.method == "getBatteryLevel") { val batteryLevel = getBatteryLevel() if (batteryLevel != -1) { result.success(batteryLevel) } else { result.error("UNAVAILABLE", "Battery level not available.", null) } } else { result.notImplemented() } } } } /Android/app/src/main/kotlin/MainActivity.kt
  • 31. @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let batteryChannel = FlutterMethodChannel(name: "samples.flutter.dev/battery", binaryMessenger: controller.binaryMessenger) batteryChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in // This method is invoked on the UI thread. guard call.method == "getBatteryLevel" else { result(FlutterMethodNotImplemented) return } self?.receiveBatteryLevel(result: result) }) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } } /ios/Runner/AppDelegate.swift
  • 32. Native Development Packages and Plugins (The Boring Flutter Development Show, Ep. 6)
  • 34. var stars = Row( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.star, color: Colors.green[500]), const Icon(Icons.star, color: Colors.black), const Icon(Icons.star, color: Colors.black), ], ); final ratings = Container( padding: const EdgeInsets.all(20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ stars, const Text( '170 Reviews', style: TextStyle( color: Colors.black, fontWeight: FontWeight.w800, fontFamily: 'Roboto', letterSpacing: 0.5, fontSize: 20, ), ), ], ), );
  • 36. - 부전공이 필요함 (Android, iOS, Web) - Platform Channel, BuildSettings - Flutter Web은 아직 시기상조 - 상태관리 라이브러리를 배우자 - GetX 외에도 bloc나 provider를 배우자 - BuildContext 개념 필요 정리
  • 37. 팀의 신규 프로젝트로 처음 시작하는 Flutter
  • 38. Android 2년차 개발자가 Flutter 프로젝트에 투입 팀의 신규 프로젝트로 처음 시작하는 Flutter 대기업 자회사의 Android 개발자로 채용됨 회사의 그룹웨어 및 신규 프로젝트를 개발하는 TF팀 팀 구성 - Android 9년차 팀장 - iOS 2년차 사원 - Android 5년차 사수
  • 39. 이해관계에 맞는 프로젝트 규모 산정 팀의 신규 프로젝트로 처음 시작하는 Flutter 프로젝트 규모에 따라 사용할 수 있는 상태관리 라이브러리가 달라짐. 일반적으로 - bloc : 대규모 - provider : 중, 소규모 - getX : 소규모 무엇보다도 팀원간의 이해와 소통 (컨벤션) 이 중요합니다.
  • 40. bloc, provider, GetX 비교 분석 [Flutter Festival GDG Songdo] GetX, provider, bloc 패턴 비교 분석 - 유병욱
  • 41. 협업 방식은 팀바팀, 사바사가 국룰입니다. 하지만, 팀의 신규 프로젝트로 처음 시작하는 Flutter 더 나은 협업을 위해서 고려해볼 몇가지 - DI - Flutter Theme - Clean Architecture - CI / CD
  • 43. Flutter Theme DevFest Songdo 2022 - Flutter Theme 디자이너와 호감작하기
  • 44. Clean Architecture [Flutter Festival GDG Songdo] Flutter에 Clean Architecture를 얹어보자 - 양수장
  • 45. CI / CD Github Actions를 활용한 Flutter 배포 자동화하기 - 양수장(GDG Songdo) I 모두콘 2022
  • 46. Tips & Best Practices [Flutter Festival GDG Songdo] Flutter 상용화 앱 프로젝트 적용기 - 손민재
  • 47. - 프로젝트 규모 산정이 최우선 - 핵심 기능이 Flutter로 구현 가능한지 여부 확인 - 협업을 위한 기술 - Flutter Theme - Clean Architecture - DI - CI / CD 정리