플러터 공식 문서 튜토리얼인 코드랩을 따라 수행한 내용을 기술한 글입니다.
오늘 만들어 볼 플러터 앱은 "newstay", "lightstream", "mainbrake", "graypine" 같은 멋진 이름을 자동으로 생성해주는 심플한 어플리케이션이다.
✅ The basics of how Flutter works
✅ Creating layouts in Flutter
✅ Connecting user interactions (like button presses) to app behavior
✅ Keeping your Flutter code organized
✅ Making your app responsive (for different screens)
✅ Achieving a consistent look & feel of your app
명령 팔레트(Shift+Cmd+P
) 열고 순서대로 작성 및 선택하기
flutter new
입력 -> Flutter : New Project
-> Application
선택
vs code 왼족 창 탐색기에서 pubspec.yaml
파일을 선택해서 아래 내용으로 바꾸기
name
은 설정한 프로젝트 이름으로 바꿔줘야한다❗️name: namer_app
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.0.1+1
environment:
sdk: '>=2.18.4 <3.0.0'
dependencies:
flutter:
sdk: flutter
english_words: ^4.0.0
provider: ^6.0.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^2.0.0
flutter:
uses-material-design: true
analysis_options.yaml
파일도 아래 코드로 바꿔준다.
include: package:flutter_lints/flutter.yaml
linter:
rules:
prefer_const_constructors: false
prefer_final_fields: false
use_key_in_widget_constructors: false
prefer_const_literals_to_create_immutables: false
prefer_const_constructors_in_immutables: false
avoid_print: false
마지막으로 lib/main.dart
를 아래 내용으로 바꿔준다
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => MyAppState(),
child: MaterialApp(
title: 'Namer App',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
),
home: MyHomePage(),
),
);
}
}
class MyAppState extends ChangeNotifier {
var current = WordPair.random();
}
class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) {
var appState = context.watch<MyAppState>();
return Scaffold(
body: Column(
children: [
Text('A random idea:'),
Text(appState.current.asLowerCase),
],
),
);
}
}
다음으로 두번째 Text
인스턴스 바로 아래에 있는, Column
의 하단에 button을 추가한다
lib/main.dart
// ...
return Scaffold(
body: Column(
children: [
Text('A random AWESOME idea:'),
Text(appState.current.asLowerCase),
// ↓ Add this.
ElevatedButton(
onPressed: () {
print('button pressed!');
},
child: Text('Next'),
),
],
),
);
// ...
Flutter가 어떻게 작동하는지 이해해보자.
lib/main.dart
// ...
void main() {
runApp(MyApp());
}
// ...
파일의 상단에는 main()
함수가 있다. 위 코드는 Flutter에게 MyApp
에 정의된 앱을 실행하라고 지시하는 역할만 수행한다.
lib/main.dart
// ...
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => MyAppState(),
child: MaterialApp(
title: 'Namer App',
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
),
home: MyHomePage(),
),
);
}
}
// ...
MyApp
클래스는 StatelessWidget
을 상속받아서 확장된다. 위젯은 모든 Flutter 앱을 빌드하는데 사용되는 요소이고, 앱 자체도 위젯이다.
나중에
StatelessWidget
과StatefulWidget
에 대한 내용을 다룰 예정이다.
MyApp
의 코드는 전체 앱을 설정한다. app-wide state를 만들고, 앱 이름을 지정하고, 시각적 테마를 정의하고, 앱의 시작점인 "Home" 위젯을 설정한다.
lib/main.dart
// ...
class MyAppState extends ChangeNotifier {
var current = WordPair.random();
}
// ...
다음으로 MyAppState
클래스는 app's...well...state를 정의한다..응..? Flutter에서 앱 상태를 관리하는 방법이 많이 존재한다. 설명하기 가장 쉬운 것 중 하나는 이 앱에서 사용하는 접근 방식인 ChangeNotifier
이다.
MyAppState
는 앱이 작동하는데 필요한 데이터를 정의한다. 지금은 임의의 단어 쌍이 있는 단일 변수 current
만 포함한다. ChangeNotifire
를 확장한다. 즉, 자신의 변경 사항을 다른 위젯에게 알릴 수 있다. 예를 들어, 현재 단어 쌍이 변경되면 앱의 일부 위젯이 알아야한다.ChangeNotifierProvider
를 사용하여 전체 앱에 생성되고 제공된다. 이렇게 하면 앱의 모든 위젯이 state를 유지할 수 있다.lib/main.dart
// ...
class MyHomePage extends StatelessWidget {
Widget build(BuildContext context) { // ← 1
var appState = context.watch<MyAppState>(); // ← 2
return Scaffold( // ← 3
body: Column( // ← 4
children: [
Text('A random AWESOME idea:'), // ← 5
Text(appState.current.asLowerCase), // ← 6
ElevatedButton(
onPressed: () {
print('button pressed!');
},
child: Text('Next'),
),
], // ← 7
),
);
}
}
// ...
마지막으로, 이미 수정한 위젯인 MyHomePage
가 있다. 아래의 번호가 매겨진 각 줄은 위 코드의 줄 번호 주석에 매핑된다.
build()
메서드를 정의한다.MyHomePage
는 watch 메서드를 사용해서 앱의 현재 상태에 대한 변경 사항을 추적한다.build
메서드는 위젯 또는 중첩된 위젯 트리를 반환해야한다. 이 경우 최상위 위젯은 Scaffold
이다. Column
은 Flutter 에서 가장 기본적인 레이아웃 위젯 중 하나이다. 원하는 수의 children을 가져와 위에서 아래로 넣는다. 기본적으로 Column은 시각적으로 하위 항목을 맨 위에 배치한다. Text
위젯을 변경했다.Text
위젯은 appState
를 사용하고, 해당 클래스의 유일한 멤버인 current
에 액세스한다. WordPair
는 asPascalCase
, SnakeCase
와 같은 몇가지 유용한 getter
를 제공한다. Column
매개변수 목록의 마지막 구성원이기 때문에 이 특정 쉼표는 여기에 있을 필요가 없다. 하지만 일반적으로 후행 쉼표는 사용하는 것이 좋다. 쉼표가 더 많은 멤버를 추가하기 좋게 만들고, Dart의 자동 서식 지정 도구가 줄 바꿈을 추가하도록 힌트 역할을 한다. 자세한 내용은 코드 서식을 참고하자 https://codelabs.developers.google.com/codelabs/flutter-codelab-first#0