
오늘의 핵심 학습 내용
- 커스텀 위젯 만들기
- 폰트 추가(yaml)
- AppBar
- Theme 적용
- ListView
component
명사 (구성) 요소, 부품여기에서 flutter가 Dart 언어를 사용하는 강점이 폭발한다.
반복되는 위젯을 클래스로 구성해서 커스텀이 가능하다는 것!!
미친 커스텀!! 돌아버린 커스텀!!
클래스를 세팅할 줄만 안다면 무서울 게 없다.
그리고 클래스 내에서 바뀌는 것들은 파라미터로 받아주면 그만이다.
그건 생성자로 세팅하면 끝.
세상에.
다트 언어 공부할 때보다 오히려 플러터에서 실전으로 사용하니 훨씬 직관적이다.
컴포넌트화 하기
main.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_recipe/recipe_list_item.dart';
import 'package:flutter_recipe/recipe_menu.dart';
import 'package:flutter_recipe/recipe_title.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(fontFamily: 'KBIZ'),
home: RecipePage(),
);
}
}
class RecipePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
Icon(CupertinoIcons.search, size: 30),
SizedBox(width: 15),
Icon(CupertinoIcons.heart, size: 30, color: Colors.redAccent),
SizedBox(width: 15),
],
),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ListView(
children: [
RecipeTitle(),
RecipeMenu(),
RecipeListItem(
"assets/images/coffee.jpg",
"맛있는 커피",
"강릉은 커피의 도시, 그 중에서도 제일은 데자뷰 로스터리임. 여기 안 가봤으면 커피의 세계를 아직 다 안다고 할 수 없다. 여기서부터 새로운 지평선이 열림.",
), // for coffee
RecipeListItem(
"assets/images/burger.jpg",
"존맛탱 버거",
"햄버거 좀 치냐? 햄버거는 맥도날드지. 그치만 거기서 제일 맛있는 건 초코썬데이라는 사실.",
), // for burger
RecipeListItem(
"assets/images/pizza.jpg",
"피자는 한물 갔음",
"1인 가구 폭증으로 피자는 혼자 못 먹어, 피자의 시대가 가고 햄버거의 시대가 왔다. 혼자의 시대가 왔다. 그래도 가끔은 피자먹고 싶엉.",
), // for pizza
],
),
),
);
}
}
recipe_title.dart
import 'package:flutter/material.dart';
class RecipeTitle extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Text("레시피", style: TextStyle(fontSize: 30));
}
}recipe_menu.dart
import 'package:flutter/material.dart';
class RecipeMenu extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Row(
children: [
menuItem(Icons.food_bank, "전체"),
SizedBox(width: 25),
menuItem(Icons.emoji_food_beverage, "음료"),
SizedBox(width: 25),
menuItem(Icons.fastfood, "버거"),
SizedBox(width: 25),
menuItem(Icons.local_pizza, "피자"),
],
),
);
}
Container menuItem(IconData icon, String text) {
// menuItem은 Container (class)에 종속되는 메서드.
return Container(
width: 60,
height: 80,
decoration: BoxDecoration(
border: Border.all(color: Colors.black12),
borderRadius: BorderRadius.circular(30),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(icon, size: 30, color: Colors.redAccent),
SizedBox(height: 5),
Text(text),
],
),
);
}
}
recipe_list_item.dart
import 'package:flutter/material.dart';
class RecipeListItem extends StatelessWidget {
RecipeListItem(this.path, this.title, this.content); // 이게 생성자 -- 이걸로 인생이 편해짐
String path;
String title;
String content;
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AspectRatio(
aspectRatio: 2 / 1,
child: ClipRRect(
borderRadius: BorderRadius.circular(20),
child: Image.asset(path, fit: BoxFit.cover),
),
),
SizedBox(height: 8),
Text(title, style: TextStyle(fontSize: 20)),
SizedBox(height: 4),
Text(content, style: TextStyle(fontSize: 12, color: Colors.black45)),
],
),
);
}
}
결과

아직 초보자인 나로서는 체력과 집중력을 많이 요하는 지금의 과정이 쉽지 만은 않지만,
어떤 결이랄까, 궁합으로 봤을 때는 나는 개발에 제법 잘 맞는 사람이다.
10년 일찍 왔어야 하는데 ㅋㅋㅋ
그치만 지금이라도 온 게 어디임. 10년 전에 왔으면 빌드맛에 빠져서 코드 깎는 노인이 되었을지도 모른다.
사업 흉내도 내보고, 빚 무서운 줄도 알고 - 이런 상태가 되었으니 단순히 코드만 짜는 게 아니라 세상을 볼 수 있게 된 거겠지.
그렇겠지 와따시…?
코드 공부 빨리 마치고 창업 아이템이나 다듬고 싶다 ㅋ
Share article