νλ¬ν° νλ‘μ νΈ κ΅¬μ± νμΌ
flutter_app
βββ android
βββ ios
βββ build
βββ lib
β βββ main.dart
βββ test
βββ pub.yaml
βββ pubspec.lock
βββ README.md
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
νλ‘μ νΈλ₯Ό μ€λͺ
νλ νμΌ
β’
νλ‘μ νΈμ λν μ€λͺ
, μ¬μ©λ², λΌμ΄μ μ€ λ±μ κΈ°λ‘ν λ§ν¬λ€μ΄ νμΌμ
λλ€.
β’
νλ‘μ νΈμ λν λ¬Έμνμ 곡μ λ₯Ό μν΄ μ¬μ©λ©λλ€.