ํ๋ฌํฐ ํ๋ก์ ํธ ๊ตฌ์ฑ ํ์ผ
android
ํ๋ฌํฐ๋ฅผ ์ปดํ์ผํ ์๋๋ก์ด๋ ๋ค์ดํฐ๋ธ ์ฝ๋๊ฐ ๋ค์ด ์๋ ๋๋ ํฐ๋ฆฌ
โข
Android ์ ํ๋ฆฌ์ผ์ด์
์ ๋น๋ํ๋ ๋ฐ ํ์ํ Android ํ๋ก์ ํธ ํ์ผ์ด ๋ค์ด ์๋ ๋๋ ํฐ๋ฆฌ์
๋๋ค.
โข
์๋๋ก์ด๋ ์ฑ์ ์ค์ ๊ณผ Gradle ๋น๋ ์คํฌ๋ฆฝํธ๊ฐ ์ฌ๊ธฐ์ ์์นํฉ๋๋ค.
ios
ํ๋ฌํฐ๋ฅผ ์ปดํ์ผํ iOS ๋ค์ดํฐ๋ธ ์ฝ๋๊ฐ ๋ค์ด ์๋ ๋๋ ํฐ๋ฆฌ
โข
iOS ์ ํ๋ฆฌ์ผ์ด์
์ ๋น๋ํ๋ ๋ฐ ํ์ํ iOS ํ๋ก์ ํธ ํ์ผ์ด ๋ค์ด ์๋ ๋๋ ํฐ๋ฆฌ์
๋๋ค.
โข
iOS ์ฑ์ ์ค์ ๊ณผ Info.plist ํ์ผ์ด ์ฌ๊ธฐ์ ์์นํฉ๋๋ค.
build
ํ๋ก์ ํธ ๋น๋ ์, ์์ฑ๋๋ ํ์ผ
โข
๋น๋๋ ์ ํ๋ฆฌ์ผ์ด์
ํ์ผ ๋ฐ ๋น๋ ์ค์ ์์ฑ๋ ๊ธฐํ ํ์ผ์ด ์ฌ๊ธฐ์ ์ ์ฅ๋ฉ๋๋ค.
โข
์ด ๋๋ ํฐ๋ฆฌ๋ .gitignore ํ์ผ์ ํฌํจ๋์ด์ผ ํฉ๋๋ค.
lib
ํ๋ฌํฐ ์ฑ ๊ฐ๋ฐ ์์ค ์ฝ๋ ํ์ผ์ ์์ฑํ๋ ๋๋ ํ ๋ฆฌ
โข
์ ํ๋ฆฌ์ผ์ด์
์ ์์ค ์ฝ๋๊ฐ ํฌํจ๋ ๋๋ ํฐ๋ฆฌ์
๋๋ค.
โข
main.dart์ ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์
์ง์
์ ๋ฐ ๋ค๋ฅธ Dart ํ์ผ๋ค์ด ์ฌ๊ธฐ์ ์์นํฉ๋๋ค.
main.dart
์ฑ ์คํ ์, ์์์ ์ด ๋๋ ๋ฉ์ธ ํ์ผ
โข
์ ํ๋ฆฌ์ผ์ด์
์ ์ง์
์ ์ด ๋๋ Dart ์ฝ๋ ํ์ผ์
๋๋ค.
โข
์ฌ๊ธฐ์์ ์ฑ์ ๊ธฐ๋ณธ ๊ตฌ์ฑ๊ณผ ํ๋ฉด ๋ ์ด์์์ด ์ ์๋ฉ๋๋ค.
// main.dart
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key});
// ์ ํ๋ฆฌ์ผ์ด์
์ ๋ฃจํธ ์์ ฏ
@override
Widget build(BuildContext context) {
return MaterialApp(
// ๋๋ฒ๊ทธ ๋ฐฐ๋ ๋นํ์ฑํ
debugShowCheckedModeBanner: false,
title: 'Flutter App', // ์ฑ ์ด๋ฆ
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter App Main Title'), // ํ ํ๋ฉด ์ ๋ชฉ
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
// ์ซ์๋ฅผ ์ฆ๊ฐ์ํค๋ ๋ฉ์๋
void _incrementCounter() {
setState(() {
_counter++;
});
}
// ์ซ์๋ฅผ ๊ฐ์์ํค๋ ๋ฉ์๋
void _decrementCounter() {
setState(() {
// ์ซ์๊ฐ 0๋ณด๋ค ํฐ ๊ฒฝ์ฐ์๋ง ๊ฐ์
_counter > 0 ? _counter-- : 0;
});
}
// ํ๋ฉด์ ๋น๋ํ๋ ๋ฉ์๋
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
SizedBox(width: 20),
// ์ซ์๋ฅผ ์ฆ๊ฐ์ํค๋ FloatingActionButton
FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Add', // ํดํ ํ
์คํธ
child: const Icon(Icons.add),
),
const Spacer(),
// ์ซ์๋ฅผ ๊ฐ์์ํค๋ FloatingActionButton
FloatingActionButton(
onPressed: _decrementCounter,
tooltip: 'Minus', // ํดํ ํ
์คํธ
child: const Icon(Icons.remove),
),
],
),
);
}
}
YAML
๋ณต์ฌ
test
ํ
์คํธ ์์ค ์ฝ๋ ํ์ผ์ด ์๋ ๋๋ ํฐ๋ฆฌ
โข
ํ
์คํธ ํ์ผ์ด ํฌํจ๋ ๋๋ ํฐ๋ฆฌ์
๋๋ค.
โข
ํ
์คํธ ์ฃผ๋ ๊ฐ๋ฐ(TDD)์ ์ง์ํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ฉฐ, ํ
์คํธ ์ฝ๋๊ฐ ์ฌ๊ธฐ์ ์์ฑ๋ฉ๋๋ค.
pubspec.yaml
ํ๋ก์ ํธ ์ด๋ฆ, ์ค๋ช
, ๋ฒ์ , ์์กด์ฑ, ์ ์ ํ์ผ(asset) ์ ๊ด๋ฆฌํ๋ ์ค์ ํ์ผ
โข
Dart ํจํค์ง ๊ด๋ฆฌ ๋ฐ ํ๋ก์ ํธ ๊ตฌ์ฑ์ ์ ์ํ๋ ํต์ฌ ํ์ผ์ธ pubspec.yaml ํ์ผ์
๋๋ค.
โข
์์กด์ฑ ํจํค์ง, ์ ํ๋ฆฌ์ผ์ด์
์ ์ด๋ฆ, ๋ฒ์ , ๋ฆฌ์์ค ๊ฒฝ๋ก ๋ฑ์ด ์ฌ๊ธฐ์ ์ ์๋ฉ๋๋ค.
# pubspec.yaml
# ํ๋ก์ ํธ์ ์ด๋ฆ
name: flutter_app
# ํ๋ก์ ํธ์ ๋ํ ๊ฐ๋จํ ์ค๋ช
description: A new Flutter project.
# ํจํค์ง๋ฅผ pub.dev์ ๊ฒ์ํ์ง ์์
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# ๋ฒ์ ์ ๋ณด
version: 1.0.0+1
# Flutter SDK ๋ฒ์ ๋ฐ ํ๊ฒฝ ์ค์
environment:
sdk: '>=2.18.2 <3.0.0'
# ์์กด์ฑ ํจํค์ง ๋ชฉ๋ก
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
# ๊ฐ๋ฐ ์ค์๋ง ํ์ํ ์์กด์ฑ ํจํค์ง ๋ชฉ๋ก
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
# Flutter ์ค์
flutter:
# Material Design ์ฌ์ฉ ์ฌ๋ถ
uses-material-design: true
YAML
๋ณต์ฌ
pubspec.lock
ํจํค์ง ๋งค๋์ ๊ฐ ์์กด์ฑ์ ๋ํ ์ ํํ ๋ฒ์ ์ ๊ด๋ฆฌํ๋ ํ์ผ
โข
ํจํค์ง ์์กด์ฑ์ ์ ํํ ๋ฒ์ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ ํ์ผ์
๋๋ค.
โข
pubspec.yaml ํ์ผ์ ๋ช
์๋ ์์กด์ฑ ๋ฒ์ ๊ณผ ์ผ์นํ๋๋ก ์๋์ผ๋ก ์์ฑ๋ฉ๋๋ค.
README.md
ํ๋ก์ ํธ๋ฅผ ์ค๋ช
ํ๋ ํ์ผ
โข
ํ๋ก์ ํธ์ ๋ํ ์ค๋ช
, ์ฌ์ฉ๋ฒ, ๋ผ์ด์ ์ค ๋ฑ์ ๊ธฐ๋กํ ๋งํฌ๋ค์ด ํ์ผ์
๋๋ค.
โข
ํ๋ก์ ํธ์ ๋ํ ๋ฌธ์ํ์ ๊ณต์ ๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค.