์ด์ Step 6 !!!
์ง๊ธ๊น์ง ์ฐ๋ฆฌ๊ฐ ๋ง๋ ์ฑ์, next ๋ฒํผ์ ๋๋ฅด๋ฉด ์ด์ ์ ๋์๋ ๋จ์ด๋ฅผ ๋ณผ ์ ์์๋ค.
๊ทธ๋์ ์ด๋ฒ ๋จ๊ณ์์๋ 'Like' ๋ฒํผ์ ๋๋ฌ, ์ํ๋ ๋จ์ด๋ฅผ ๊ธฐ์ตํด๋ณด๋ ค๊ณ ํ๋ค.
์ด๋ฒ ๋ชฉํ๋ ๋ค์ ํ๋ฉด๊ณผ ๊ฐ๋ค.
Add the business logic
MyAppState ์์ ๋ค์๊ณผ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ ํด๋ณด์.
lib/main.dart
// ...
class MyAppState extends ChangeNotifier {
var current = WordPair.random();
void getNext() {
current = WordPair.random();
notifyListeners();
}
// ↓ Add the code below.
var favorites = <WordPair>[];
void toggleFavorite() {
if (favorites.contains(current)) {
favorites.remove(current);
} else {
favorites.add(current);
}
notifyListeners();
}
}
// ...
- ์ง๊ธ ์ฐ๋ฆฌ๋ favorites ๋ผ๊ณ ๋ถ๋ฆฌ๋ property๋ฅผ MyAppState์ ์ถ๊ฐํ ๊ฒ์ด๋ค. ์ด property๋ ๋น ๋ฆฌ์คํธ [] ๋ก ์ด๊ธฐํ๋๋ค.
- ๋ํ, generics๋ฅผ ์ฌ์ฉํ์ฌ ๋ชฉ๋ก์ ๋จ์ด์์ธ <WordPair>[]๋ง ํฌํจํ ์ ์๋๋ก ์ง์ ํ ๊ฒ์ด๋ค. ์ด๋ ์ฐ๋ฆฌ ์ฑ์ ๋ ๊ฐ๋ ฅํ๊ฒ ๋ง๋๋ ๋ฐ ๋์์ ์ฃผ๋๋ฐ, Dart๊ฐ WordPair ์ด์ธ์ ๊ฒ์ ์ถ๊ฐํ๋ ค๊ณ ํ ๋ ์ฐ๋ฆฌ ์ฑ์ ์คํํ๋ ๊ฒ์กฐ์ฐจ ๊ฑฐ๋ถํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฆ, WordPair ์ด์ธ์ ๊ฒ์ ์ถ๊ฐํ์ง ๋ชปํ๋๋ก ํ๋ ๊ฒ์ด๋ค. ์ด๋ ๊ฒ ํ๋ฉด, favorites ๋ชฉ๋ก์ ํตํด ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฐ์ฒด(ex. null)๊ฐ ์จ๊ฒจ์ง ์ ์์์ ์ ์ ์๋ค.
List ๋์ Set์ ์ฌ์ฉํด๋ ๋๋ค. Set์ []๊ฐ ์๋, {}์ ํตํด ํํํ๋ค. - ๋ํ, toggleFavorite() ๋ฉ์๋๋ฅผ ์ถ๊ฐํ ์ ์๋๋ฐ, ์ด๋ ๋ง์ฝ favorites ๋ฆฌ์คํธ์ ํ์ฌ ๋จ์ด๊ฐ ์๋ ๊ฒฝ์ฐ ์ด๋ฅผ ์์ ๊ฑฐ๋, ๋ง์ฝ ๋ฆฌ์คํธ์ ์๋ค๋ฉด ์ถ๊ฐํ ์ ์๋ค. ์ด ๋ ๊ฒฝ์ฐ, ์ฝ๋๋ notifyListerners();๋ฅผ ํธ์ถํด์ผ ํ๋ค.
Add the button
์ด์ ์ข์์ ๋ฒํผ์ ๋ง๋ค์ด์ 'Next' ๋ฒํผ ์ผ์ชฝ์ ๋ง๋ค์ด์ค ๊ฒ์ด๋ค. ๋ฒํผ์ Next ์์ ๋๊ธฐ ์ํด์๋ Row ์์ ฏ์ด ํ์ํ๋ค.
๋จผ์ ํ์ฌ ์กด์ฌํ๋ ๋ฒํผ์ Row๋ก ๊ฐ์ผ๋ค.
MyHomePage์ build()๋ฉ์๋๋ก ๊ฐ์, ElevatedButton ์์ ์ปค์๋ฅผ ๋๊ณ Refactor ๋ฉ๋ด๋ฅผ ์ด์ด Wrap with Row๋ฅผ ์ ํํ๋ค.
์ด๋ฅผ ์ ์ฅํ๋ฉด, Column์ ์ ์ฉํ์ ๋์ ๋น์ทํ๊ฒ children์ด ์ผ์ชฝ์ ์น์ฐ์ ธ์ง ๊ฒ์ ํ์ธํ ์ ์๋ค. (Column์ ์๋ก..!)
์ด๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ชจ์์ผ๋ก ์์ ํ๊ธฐ ์ํด์๋ Column์์ ํ ๊ฒ๊ณผ ๋น์ทํ๊ฒ center๋ฅผ ๋ง์ถฐ์ฃผ๋ฉด ๋๋ค.
Row์์๋ mainAxisAlignment๋ฅผ ํตํด ๋ง์ถ ์ ์๋ค.
์ด๋ฅผ ์ ์ฉํ ์ฝ๋์ด๋ค.
lib/main.dart
// ...
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var appState = context.watch<MyAppState>();
var pair = appState.current;
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BigCard(pair: pair),
SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min, // ← Add this.
children: [
ElevatedButton(
onPressed: () {
appState.getNext();
},
child: Text('Next'),
),
],
),
],
),
),
);
}
}
// ...
๋ค์ Row๋ฅผ ์ ์ฉํ๊ธฐ ์ ์ผ๋ก ๋์๊ฐ ๊ฒ์ ๋ณผ ์ ์๋ค. ์ฆ, ์ผํฐ๊ฐ ๋ง์ถฐ์ง ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด์ , ์ฐ๋ฆฌ๋ Like button์ ์ถ๊ฐํด์ ์ด๋ฅผ toggleFavorites()์ ์ฐ๊ฒฐํ ๊ฒ์ด๋ค.
์ด๋ฅผ ์ํด, ์ฝ๋๋ฉ์์๋ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ๋์ ํด๋ณด๊ธธ ๊ถ์ฅํ๊ณ ์๋ค.
๋ชจ๋ ์ง์ ํ ๋ฒ ํด๋ณด๊ธธ..!
- MyHomePage์ ๋ฒํผ์ ์ถ๊ฐํ๋ค.
- ElevatedButton.icon()์ ์ฌ์ฉํ๋ค.
- build ๋ฉ์๋์ ๊ฐ์ฅ ์ ๋ถ๋ถ์ word pair๊ฐ favorite์ผ๋ก ์ ํ๋๋์ง์ ์ฌ๋ถ์ ๋ฐ๋ผ ์ ์ ํ icon์ ์ ํํ๋ค.
- SizedBox๋ฅผ ์ฌ์ฉํด์ ๋ ๋ฒํผ ์ฌ์ด์ ์ฌ๋ฐฑ์ ๋๋ค.
์ฝ๋๋ฉ์์ ์ ๊ณตํ ์ฝ๋๋ ์ด๋ฌํ๋ค
lib/main.dart
// ...
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var appState = context.watch<MyAppState>();
var pair = appState.current;
// ↓ Add this.
IconData icon;
if (appState.favorites.contains(pair)) {
icon = Icons.favorite;
} else {
icon = Icons.favorite_border;
}
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BigCard(pair: pair),
SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
children: [
// ↓ And this.
ElevatedButton.icon(
onPressed: () {
appState.toggleFavorite();
},
icon: Icon(icon),
label: Text('Like'),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: () {
appState.getNext();
},
child: Text('Next'),
),
],
),
],
),
),
);
}
}
// ...
์ด๋ ๊ฒ ํ๋ฉด, ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ ์ ์๋ค!!
์ด์ step 6์ด ๋๋ฌ๋ค!!!
๋ค์ ์คํ ์์๋ ์ฐ๋ฆฌ๊ฐ ์ข์์ ํ ๋จ์ด๊ฐ ๋ฌด์์ธ์ง๋ฅผ ๋ณด์ฌ์ฃผ๋๋ก ํ ์์ !!
์ ์ฒด ์ฝ๋๋ฅผ ์ฒจ๋ถํ๋ค !
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});
@override
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();
void getNext() {
current = WordPair.random();
notifyListeners();
}
var favorites = <WordPair>[];
void toggleFavorite() {
if (favorites.contains(current)) {
favorites.remove(current);
} else {
favorites.add(current);
}
notifyListeners();
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var appState = context.watch<MyAppState>();
var pair = appState.current;
IconData icon;
if (appState.favorites.contains(pair)) {
icon = Icons.favorite;
} else {
icon = Icons.favorite_border;
}
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
BigCard(pair: pair),
SizedBox(height: 10),
Row(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton.icon(
onPressed: () {
appState.toggleFavorite();
},
icon: Icon(icon),
label: Text('Like'),
),
SizedBox(width: 10),
ElevatedButton(
onPressed: () {
appState.getNext();
},
child: Text('Next'),
),
],
),
],
),
),
);
}
}
class BigCard extends StatelessWidget {
const BigCard({
Key? key,
required this.pair,
}) : super(key: key);
final WordPair pair;
@override
Widget build(BuildContext context) {
var theme = Theme.of(context);
var style = theme.textTheme.displayMedium!.copyWith(
color: theme.colorScheme.onPrimary,
);
return Card(
color: theme.colorScheme.primary,
child: Padding(
padding: const EdgeInsets.all(20),
child: Text(
pair.asLowerCase,
style: style,
semanticsLabel: pair.asPascalCase,
),
),
);
}
}
'๐ง flutter' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[flutter] ์๋กญ๊ฒ ๋ฐ๋ codelab (step5) (0) | 2023.02.08 |
---|---|
[flutter] ์๋กญ๊ฒ ๋ฐ๋ codelab (step1-step4) (0) | 2023.02.07 |
์์ดํฐ ๋ฌด์ ๋๋ฒ๊น (0) | 2022.10.30 |
[Flutter] flutter iphone ์ฐ๋ํ๊ธฐ (2) | 2022.08.25 |
flutter album ์ ๊ทผ (0) | 2022.07.08 |