import 'package:flutter/material.dart';
class RecipeListItem extends StatelessWidget {
final String imageName;
final String title;
const RecipeListItem(this.imageName, this.title, {Key? key})
: super(key: key);
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
AspectRatio(
aspectRatio: 2 / 1,
child: ClipRRect(
borderRadius: BorderRadius.circular(20.0),
child: Image.asset(
"assets/images/$imageName.jpeg",
fit: BoxFit.cover,
),
),
),
const SizedBox(
height: 10,
),
Text(
title,
style: const TextStyle(fontSize: 20),
)
],
),
);
}
}
import 'package:flutter/material.dart';
class RecipeMenu extends StatelessWidget {
const RecipeMenu({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 20),
child: Row(
children: [
_buildMenuItem(Icons.food_bank, "All"),
const Spacer(),
_buildMenuItem(Icons.emoji_food_beverage, "Coffee"),
const Spacer(),
_buildMenuItem(Icons.fastfood, "Burger"),
const Spacer(),
_buildMenuItem(Icons.local_pizza, "Pizza"),
],
),
);
}
}
Widget _buildMenuItem(IconData mIcon, String text) {
return Container(
width: 90,
height: 55,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.black12),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
mIcon,
color: Colors.redAccent,
size: 30,
),
const SizedBox(height: 5),
Text(text, style: const TextStyle(color: Colors.black87)),
],
),
);
}
import 'package:flutter/material.dart';
class RecipeTitle extends StatelessWidget {
const RecipeTitle({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.only(top :20),
child: Text(
"Recipes",
style: TextStyle(fontSize: 30),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_recipe/components/recipe_list_item.dart';
import 'package:flutter_recipe/components/recipe_menu.dart';
import 'package:flutter_recipe/components/recipe_title.dart';
AppBar _buildRecipeAppBar(){
return AppBar(
backgroundColor: Colors.white, // 배경색
elevation: 1.0, // 그림자
actions: const [
Icon(
CupertinoIcons.search,
color: Colors.black,
),
SizedBox(width: 15),
Icon(
CupertinoIcons.heart,
color: Colors.redAccent,
),
SizedBox(width: 15),
],
);
}
class RecipePage extends StatelessWidget{
const RecipePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: _buildRecipeAppBar(),
body: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: ListView(
children: const [
RecipeTitle(),
RecipeMenu(),
RecipeListItem("coffee", "Made Coffee"),
RecipeListItem("burger", "Maade Burger"),
RecipeListItem("pizza", "Made Pizza"),
],
),
),
);
}
}

import 'package:flutter/material.dart';
class ProfileButtons extends StatelessWidget {
const ProfileButtons({super.key});
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildFollowButton(),
_buildMessageButton(),
],
);
}
Widget _buildFollowButton() {
return InkWell(
onTap: () {
print("Follow 버튼 클릭됨");
},
child: Container(
alignment: Alignment.center,
width: 150,
height: 45,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(10),
),
child: const Text(
"Follow",
style: TextStyle(color: Colors.white),
),
),
);
}
Widget _buildMessageButton() {
return InkWell(
onTap: () {
print("Message 버튼 클릭됨");
},
child: Container(
alignment: Alignment.center,
width: 150,
height: 45,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
border: Border.all(),
),
child: const Text(
"Message",
style: TextStyle(color: Colors.black),
),
),
);
}
}
import 'package:flutter/material.dart';
class ProfileCountInfo extends StatelessWidget {
const ProfileCountInfo({super.key});
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildInfo("50", "Posts"),
_buildLine(),
_buildInfo("10", "Likes"),
_buildLine(),
_buildInfo("3", "Share"),
],
);
}
Widget _buildInfo(String count, String title) {
return Column(
children: [
Text(
count,
style: const TextStyle(fontSize: 15),
),
const SizedBox(height: 2),
Text(
title,
style: const TextStyle(fontSize: 15),
),
],
);
}
Widget _buildLine() {
return Container(width: 2, height: 60, color: Colors.blue);
}
}
import 'package:flutter/material.dart';
class ProfileDrawer extends StatelessWidget {
const ProfileDrawer({super.key});
Widget build(BuildContext context) {
return SafeArea(
child: Container(
width: 200,
height: double.infinity,
color: Colors.white,
child: Column(
children: [
_buildDrawerItem(Icons.person, "내 정보"),
_buildDrawerItem(Icons.person, "내 게시글 보기"),
_buildDrawerItem(Icons.settings, "설정"),
],
),
),
);
}
}
Widget _buildDrawerItem(IconData iconData, String content) {
return Container(
decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.black12))),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(iconData),
const SizedBox(width: 5.0),
Text(content),
],
),
),
);
}
import 'package:flutter/material.dart';
class ProfileHeader extends StatelessWidget {
const ProfileHeader({super.key});
Widget build(BuildContext context) {
return Row(
// 1
children: [
const SizedBox(width: 20),
_buildHeaderAvatar(),
const SizedBox(width: 20),
_buildHeaderProfile(),
],
);
}
Widget _buildHeaderAvatar() {
return const SizedBox(
width: 100,
height: 100,
child: CircleAvatar(
backgroundImage: AssetImage("assets/avatar.png"),
),
);
}
Widget _buildHeaderProfile() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
"Anonymous",
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.w700,
),
),
Text(
"개발자",
style: TextStyle(
fontSize: 20,
),
),
Text(
"프론트엔드, 백엔드, 데이터베이스",
style: TextStyle(
fontSize: 15,
),
),
],
);
}
}
import 'package:flutter/material.dart';
class ProfileTab extends StatefulWidget {
const ProfileTab({super.key});
State<ProfileTab> createState() => _ProfileTabState();
}
class _ProfileTabState extends State<ProfileTab> with SingleTickerProviderStateMixin {
TabController? _tabController;
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
Widget build(BuildContext context) {
return Column(
children: [
_buildTabBar(),
Expanded(child: _buildTabBarView()),
],
);
}
Widget _buildTabBar() {
return TabBar(
controller: _tabController,
tabs: const [
Tab(icon: Icon(Icons.image)),
Tab(icon: Icon(Icons.article)),
],
);
}
Widget _buildTabBarView() {
return TabBarView(
controller: _tabController,
children: [
GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisSpacing: 10,
crossAxisCount: 3,
mainAxisSpacing: 10,
),
itemCount: 42,
itemBuilder: (context, index) {
return Image.network(
"https://picsum.photos/id/${index + 1}/200/200");
},
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 10.0),
child: ListView(
children: [
_buildArticleItem("2023년에 배워야 할 10가지 프로그래밍 언어", true),
_buildArticleItem("객체 지향 프로그래밍을 마스터하는 방법", false),
_buildArticleItem("React 및 Node.js로 웹 애플리케이션 구축", true),
_buildArticleItem("코드 디버깅을 위한 모범 사례", false),
_buildArticleItem("Python을 사용한 기계 학습 소개", true),
_buildArticleItem("iOS 및 Android용 모바일 앱 개발", false),
_buildArticleItem("보안 코딩: 사이버 공격으로부터 애플리케이션 보호", false),
_buildArticleItem("오픈 소스 소프트웨어의 세계 탐색", false),
_buildArticleItem("Django로 RESTful API를 구축하는 방법", true),
_buildArticleItem("클라우드 컴퓨팅 및 AWS 시작하기", false),
_buildArticleItem("Unity 및 C#으로 게임 만들기", true),
_buildArticleItem("테스트 주도 개발: 테스트로 더 나은 코드 작성", false),
_buildArticleItem("프론트 엔드 웹 개발을 위한 최고의 도구", true),
_buildArticleItem("성능 및 확장성을 위한 코드 최적화", false),
],
),
),
],
);
}
}
Widget _buildArticleItem(String content, bool isImage) {
return Padding(
padding: const EdgeInsets.only(top: 10),
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.black12),
borderRadius: const BorderRadius.all(Radius.circular(5.0))),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: [
Text(
content,
style: const TextStyle(fontSize: 15),
),
isImage ? const Icon(Icons.comment, size: 15) : Container()
],
),
),
),
);
}


import 'package:flutter/material.dart';
import 'package:flutter_login/components/custom_text_form_field.dart';
import 'package:flutter_login/size.dart';
class CustomForm extends StatelessWidget {
CustomForm({super.key});
final _formKey = GlobalKey<FormState>(); // 1. 글로벌 key
Widget build(BuildContext context) {
return Form(
// 2. 글로벌 key를 Form 태그에 연결하여 해당 key로 Form의 상태를 관리할 수 있다.
key: _formKey,
child: Column(
children: [
const CustomTextFormField("Email"),
const SizedBox(height: mediumGap),
const CustomTextFormField("Password"),
const SizedBox(height: largeGap),
// 3. TextButton 추가
TextButton(
onPressed: () {
// 3. 유효성 검사
if (_formKey.currentState!.validate()) {
Navigator.pushNamed(context, "/home");
}
},
child: const Text("Login"),
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_login/size.dart';
class CustomTextFormField extends StatelessWidget {
final String text;
const CustomTextFormField(this.text, {super.key});
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(text),
const SizedBox(height: smallGap),
TextFormField(
validator: (value) => value!.isEmpty
? "Please enter some text"
: null, // 1. 값이 없으면 Please enter some text 경고 화면 표시
obscureText:
// 2. 해당 TextFormField가 비밀번호 입력 양식이면 **** 처리 해주기
text == "Password" ? true : false,
decoration: InputDecoration(
hintText: "Enter $text",
enabledBorder: OutlineInputBorder(
// 3. 기본 TextFormField 디자인
borderRadius: BorderRadius.circular(20),
),
focusedBorder: OutlineInputBorder(
// 4. 손가락 터치시 TextFormField 디자인
borderRadius: BorderRadius.circular(20),
),
errorBorder: OutlineInputBorder(
// 5. 에러발생시 TextFormField 디자인
borderRadius: BorderRadius.circular(20),
),
focusedErrorBorder: OutlineInputBorder(
// 5. 에러가 발생 후 손가락을 터치했을 때 TextFormField 디자인
borderRadius: BorderRadius.circular(20),
),
),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class Logo extends StatelessWidget {
final String title;
const Logo(this.title, {super.key});
Widget build(BuildContext context) {
return Column(
children: [
SvgPicture.asset(
"assets/logo.svg",
height: 70,
width: 70,
),
Text(
title,
style: const TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_login/components/logo.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
const SizedBox(height: 200),
const Logo("Care Soft"),
const SizedBox(height: 50),
TextButton(
onPressed: () {
Navigator.pop(context); // 1. 화면 스택 제거
},
child: const Text("Get Started"),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_login/components/custom_form.dart';
import 'package:flutter_login/components/logo.dart';
import 'package:flutter_login/size.dart';
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: ListView(
children: [
const SizedBox(height: xlargeGap),
const Logo("Login"),
const SizedBox(height: largeGap), // 1. 추가
CustomForm(), // 2. 추가
],
),
),
);
}
}


import 'package:flutter/material.dart';
// 사용하지 않음
class ColorIcon extends StatelessWidget {
final Color mColor;
const ColorIcon(this.mColor, {super.key});
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 10),
child: Stack(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(),
shape: BoxShape.circle,
),
),
Positioned(
left: 5,
top: 5,
child: ClipOval(
child: Container(
color: mColor,
width: 40,
height: 40,
),
),
)
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_cart/constants.dart';
// 사용하지 않음
class ProductSelectorButton extends StatelessWidget {
final int id;
final int selectedIconNum;
final IconData mIcon;
final Function changeIcon;
const ProductSelectorButton(this.id, this.selectedIconNum, this.mIcon, this.changeIcon, {super.key});
Widget build(BuildContext context) {
return Container(
width: 70,
height: 70,
decoration: BoxDecoration(
color: id == selectedIconNum ? kAccentColor : kSecondaryColor,
borderRadius: BorderRadius.circular(20),
),
child: IconButton(
icon: Icon(mIcon, color: Colors.black),
onPressed: () {
changeIcon(id);
},
),
);
}
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cart/constants.dart';
class ShoppingCartDetail extends StatelessWidget {
const ShoppingCartDetail({super.key});
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(40),
),
child: Padding(
padding: const EdgeInsets.all(30.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildDetailNameAndPrice(),
_buildDetailRatingAndReviewCount(),
_buildDetailColorOptions(),
_buildDetailButton(context),
],
),
),
);
}
Widget _buildDetailNameAndPrice() {
return Padding(
padding: const EdgeInsets.only(bottom: 10),
child: Row(
// 1. spaceBetween 이 적용되면 양 끝으로 벌어진다.
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: const [
Text(
"Urban Soft AL 10.0",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
Text(
"\$699",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
),
)
],
),
);
}
Widget _buildDetailRatingAndReviewCount() {
return Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Row(
children: const [
Icon(Icons.star, color: Colors.yellow),
Icon(Icons.star, color: Colors.yellow),
Icon(Icons.star, color: Colors.yellow),
Icon(Icons.star, color: Colors.yellow),
Icon(Icons.star, color: Colors.yellow),
// 2. Spacer()로 Icon위젯과 Text위젯을 양끝으로 벌릴 수 있다. spaceBetween과 동일
Spacer(),
Text("review "),
Text("(26)", style: TextStyle(color: Colors.blue)),
],
),
);
}
Widget _buildDetailColorOptions() {
return Padding(
padding: const EdgeInsets.only(bottom: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Color Options"),
const SizedBox(height: 10),
Row(
children: [
// 3. 동일한 색상 아이콘을 재사용하기 위해 함수로 관리
_buildDetailIcon(Colors.black),
_buildDetailIcon(Colors.green),
_buildDetailIcon(Colors.orange),
_buildDetailIcon(Colors.grey),
_buildDetailIcon(Colors.white),
],
),
],
),
);
}
// 4. 다른 화면에서도 재사용하면 공통 컴포넌트 위젯으로 관리하는 것이 좋다.
Widget _buildDetailIcon(Color mColor) {
return Padding(
padding: const EdgeInsets.only(right: 10),
// 5. Stack의 첫 번째 Container 위젯위에 Positioned 위젯이 올라가는 형태
child: Stack(
children: [
Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(),
shape: BoxShape.circle,
),
),
Positioned(
left: 5,
top: 5,
child: ClipOval(
child: Container(
color: mColor,
width: 40,
height: 40,
),
),
)
],
),
);
}
// 6. 다른 화면에서도 재사용하려면 함수가 아닌 공통 컴포넌트 위젯으로 관리하는 것이 좋다.
Widget _buildDetailButton(BuildContext context) {
return Align(
child: TextButton(
onPressed: () {
showCupertinoDialog(
// 1. 추가
context: context,
builder: (context) => CupertinoAlertDialog(
title: const Text("장바구니에 담으시겠습니까?"),
actions: [
CupertinoDialogAction(
child: const Text("확인"),
onPressed: () {
Navigator.pop(context);
},
),
],
),
);
},
style: TextButton.styleFrom(
backgroundColor: kAccentColor,
minimumSize: const Size(300, 50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
child: const Text(
"Add to Cart",
style: TextStyle(color: Colors.white),
),
),
);
}
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cart/constants.dart';
class ShoppingCartHeader extends StatefulWidget {
const ShoppingCartHeader({super.key});
State<ShoppingCartHeader> createState() => _ShoppingCartHeaderState();
}
class _ShoppingCartHeaderState extends State<ShoppingCartHeader> {
int selectedId = 0;
List<String> selectedPic = [
"assets/p1.jpeg",
"assets/p2.jpeg",
"assets/p3.jpeg",
"assets/p4.jpeg",
];
Widget build(BuildContext context) {
return Column(
children: [
_buildHeaderPic(),
_buildHeaderSelector(),
],
);
}
Widget _buildHeaderPic() {
return Padding(
padding: const EdgeInsets.all(16.0),
child: AspectRatio(
aspectRatio: 5 / 3,
child: Image.asset(
selectedPic[selectedId],
fit: BoxFit.cover,
),
),
);
}
Widget _buildHeaderSelector() {
return Padding(
padding: const EdgeInsets.only(left: 30, right: 30, top: 10, bottom: 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_buildHeaderSelectorButton(0, Icons.directions_bike),
_buildHeaderSelectorButton(1, Icons.motorcycle),
_buildHeaderSelectorButton(2, CupertinoIcons.car_detailed),
_buildHeaderSelectorButton(3, CupertinoIcons.airplane),
],
),
);
}
// 1. 다른 화면에서도 재사용하면 공통 컴포넌트 위젯으로 관리하는 것이 좋다.
Widget _buildHeaderSelectorButton(int id, IconData mIcon) {
return Container(
width: 70,
height: 70,
decoration: BoxDecoration(
color: id == selectedId ? kAccentColor : kSecondaryColor,
borderRadius: BorderRadius.circular(20),
),
child: IconButton(
icon: Icon(mIcon, color: Colors.black),
onPressed: () {
setState(() {
selectedId = id;
});
},
),
);
}
}
import 'package:flutter/material.dart';
const kPrimaryColor = MaterialColor(
0xFFeeeeee,
<int, Color>{
50: Color(0xFFeeeeee),
100: Color(0xFFeeeeee),
200: Color(0xFFeeeeee),
300: Color(0xFFeeeeee),
400: Color(0xFFeeeeee),
500: Color(0xFFeeeeee),
600: Color(0xFFeeeeee),
700: Color(0xFFeeeeee),
800: Color(0xFFeeeeee),
900: Color(0xFFeeeeee),
},
);
const kSecondaryColor = Color(0xFFc6c6c6); // 기본 버튼 색
const kAccentColor = Color(0xFFff7643); // 활성화 버튼 색
import 'package:flutter/material.dart';
import 'package:flutter_cart/constants.dart';
ThemeData theme() {
return ThemeData(
primarySwatch: kPrimaryColor,
scaffoldBackgroundColor: kPrimaryColor,
);
}
import 'package:flutter/material.dart';
import 'package:flutter_cart/components/shoppingcart_detail.dart';
import 'package:flutter_cart/components/shoppingcart_header.dart';
import 'package:flutter_cart/theme.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
theme: theme(),
home: const ShoppingCartPage(),
);
}
}
class ShoppingCartPage extends StatelessWidget {
const ShoppingCartPage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: _buildShoppingCartAppBar(),
body: ListView(
children: const [
ShoppingCartHeader(),
ShoppingCartDetail(),
],
),
);
}
AppBar _buildShoppingCartAppBar() {
return AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {},
),
actions: [
IconButton(
icon: const Icon(Icons.shopping_cart),
onPressed: () {},
),
const SizedBox(width: 16),
],
elevation: 0.0,
);
}
}


