# Flutter ์
๋ฌธ ๊ฐ์ด๋
## ํ์ต ๋ชฉํ
Flutter๋ก iOS/Android ์ฑ์ ๋์์ ๊ฐ๋ฐํฉ๋๋ค.
## 1. Flutter๋?
Google์ด ๋ง๋ ํฌ๋ก์คํ๋ซํผ UI ํ๋ ์์ํฌ์
๋๋ค.
- ๋จ์ผ ์ฝ๋๋ฒ ์ด์ค๋ก iOS/Android/Web
- ๋น ๋ฅธ ํซ ๋ฆฌ๋ก๋
- ํ๋ถํ ์์ ฏ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๋ค์ดํฐ๋ธ ์ฑ๋ฅ
## 2. ์ค์น
flutter.dev์์ SDK ๋ค์ด๋ก๋
ํ๊ฒฝ๋ณ์ PATH์ flutter/bin ์ถ๊ฐ
flutter doctor
flutter create myapp
cd myapp
flutter run
## 3. ํ๋ก์ ํธ ๊ตฌ์กฐ
lib/main.dart - ์ฑ ์์์
pubspec.yaml - ์์กด์ฑ ๊ด๋ฆฌ
android/ - Android ์ค์
ios/ - iOS ์ค์
## 4. ๊ธฐ๋ณธ ์ฑ ๊ตฌ์กฐ
import "package:flutter/material.dart";
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("My App")),
body: Center(child: Text("Hello Flutter")),
),
);
}
}
## 5. StatelessWidget vs StatefulWidget
StatelessWidget - ์ํ ์์:
class Greeting extends StatelessWidget {
final String name;
Greeting({required this.name});
Widget build(BuildContext context) {
return Text("Hello, $name");
}
}
StatefulWidget - ์ํ ์์:
class Counter extends StatefulWidget {
_CounterState createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int count = 0;
Widget build(BuildContext context) {
return Column(
children: [
Text("Count: $count"),
ElevatedButton(
onPressed: () => setState(() => count++),
child: Text("Add"),
),
],
);
}
}
## 6. ๊ธฐ๋ณธ ์์ ฏ
๋ ์ด์์:
Container, Row, Column, Stack
Padding, Center, Expanded, Flexible
ListView, GridView
์
๋ ฅ:
Text, TextField, TextFormField
ElevatedButton, TextButton, IconButton
Checkbox, Switch, Radio, Slider
ํ์:
Image, Icon, CircularProgressIndicator
Card, ListTile, Chip
## 7. ๋ ์ด์์
Column (์ธ๋ก):
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text("A"), Text("B")],
)
Row (๊ฐ๋ก):
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [Icon(Icons.star), Text("Rating")],
)
Stack (๊ฒน์นจ):
Stack(
children: [
Image.network(url),
Positioned(bottom: 10, child: Text("Caption")),
],
)
## 8. ๋ค๋น๊ฒ์ด์
๊ธฐ๋ณธ ์ด๋:
Navigator.push(context, MaterialPageRoute(
builder: (context) => DetailPage(),
));
๋ค๋ก๊ฐ๊ธฐ:
Navigator.pop(context);
Named Routes:
MaterialApp(
routes: {
"/": (context) => HomePage(),
"/detail": (context) => DetailPage(),
},
)
Navigator.pushNamed(context, "/detail");
## 9. HTTP ํต์
pubspec.yaml์ http ์ถ๊ฐ:
dependencies:
http: ^1.1.0
import "package:http/http.dart" as http;
import "dart:convert";
Future<List<User>> fetchUsers() async {
final response = await http.get(Uri.parse("https://api.example.com/users"));
if (response.statusCode == 200) {
final List data = json.decode(response.body);
return data.map((e) => User.fromJson(e)).toList();
}
throw Exception("Failed to load");
}
## 10. ์ํ ๊ด๋ฆฌ
Provider:
dependencies:
provider: ^6.0.0
ChangeNotifierProvider(
create: (context) => CartModel(),
child: MyApp(),
)
Consumer<CartModel>(
builder: (context, cart, child) {
return Text("Items: ${cart.items.length}");
},
)
context.read<CartModel>().addItem(item);
context.watch<CartModel>().items;
## 11. ๋ก์ปฌ ์ ์ฅ
SharedPreferences:
final prefs = await SharedPreferences.getInstance();
await prefs.setString("token", "abc123");
final token = prefs.getString("token");
SQLite (sqflite):
final db = await openDatabase("app.db");
await db.insert("users", {"name": "Kim"});
final users = await db.query("users");
## 12. ๋น๋ ๋ฐ ๋ฐฐํฌ
Android APK:
flutter build apk --release
Android App Bundle:
flutter build appbundle
iOS:
flutter build ios --release
Web:
flutter build web
## ์ถ์ฒ ํ์ต ์์
1. Dart ์ธ์ด ๊ธฐ์ด
2. ๊ธฐ๋ณธ ์์ ฏ ์ตํ๊ธฐ
3. ๋ ์ด์์ ๋ง์คํฐ
4. ์ํ ๊ด๋ฆฌ ์ดํด
5. API ์ฐ๋ ๋ฐ ๋ฐฐํฌ