오늘은 그동안 작성한 코드를 수정하며 최종 마무리를 지었다.
-main.dart
import 'package:fiveguys/button.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'editPageTwo.dart';
import 'foodDetail.dart';
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => FoodDetails(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
const FirstPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Column(
children: [
const SizedBox(
height: 80,
),
Padding(
padding: const EdgeInsets.only(
bottom: 40.0,
),
child: Image.network(
"https://i.ibb.co/Gnmk7yV/2023-07-11-9-26-14.pngp",
height: 400,
fit: BoxFit.fill,
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 24),
child: Row(
children: [
AButton(),
Spacer(),
BButton(),
Spacer(),
CButton(),
],
),
),
Padding(
padding:
const EdgeInsets.symmetric(horizontal: 80, vertical: 16),
child: Row(
children: [EButton(), Spacer(), DButton()],
),
)
],
),
),
),
),
);
}
}
-profille.dart
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'editPageTwo.dart';
import 'package:url_launcher/url_launcher.dart';
import 'foodDetail.dart';
class Profile extends StatefulWidget {
final String foodName;
final Map<String, String> foodDetails;
const Profile({Key? key, required this.foodName, required this.foodDetails})
: super(key: key); // Update the constructor
@override
_ProfileState createState() => _ProfileState();
}
class _ProfileState extends State<Profile> {
Map<String, String> foodDetails = {};
@override
void initState() {
super.initState();
final foodDetailsProvider =
Provider.of<FoodDetails>(context, listen: false);
foodDetailsProvider.setFoodDetails(widget.foodName);
if (widget.foodDetails != null) {
foodDetails = widget.foodDetails;
}
}
@override
Widget build(BuildContext context) {
final image = TextEditingController(text: '이미지');
final nameController = TextEditingController(text: '이름');
final manufactureDateController = TextEditingController(text: '제조년월');
final date = TextEditingController(text: '성분');
final origin = TextEditingController(text: '원산지');
final nutritionalInformation = TextEditingController(text: '영양정보');
final github = TextEditingController(text: '깃허브');
final velog = TextEditingController(text: '벨로그');
var foodDetailsProvider = Provider.of<FoodDetails>(context, listen: true);
var foodDetails = Provider.of<FoodDetails>(context, listen: true).details;
return Scaffold(
appBar: AppBar(
leading: BackButton(
color: Colors.redAccent,
onPressed: () {
Navigator.pop(context, foodDetails);
},
),
actions: [
IconButton(
icon: Icon(
CupertinoIcons.pencil_ellipsis_rectangle,
size: 30,
),
color: Colors.redAccent,
iconSize: 30,
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => EditPage(
image: image,
foodDetails: foodDetails,
nameController: nameController,
manufactureDateController: manufactureDateController,
date: date,
origin: origin,
nutritionalInformation: nutritionalInformation,
github: github,
velog: velog,
),
),
);
if (result != null) {
setState(() {
foodDetails = result;
});
foodDetailsProvider.updateFoodDetails(widget.foodName, result);
}
},
),
],
elevation: 0,
backgroundColor: Colors.white,
title: Text(
" FIVE GUYS ",
style: TextStyle(
color: Colors.redAccent,
fontWeight: FontWeight.w900,
fontSize: 30,
),
),
),
body: SingleChildScrollView(
child: Container(
color: Colors.redAccent,
height: 890,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 25),
child: Column(
children: [
Stack(
children: [
Center(
child: Container(
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular(200),
),
color: Colors.white,
),
height: 300,
width: 300,
),
),
Row(
children: [
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(
left: 65.0,
right: 30.0,
top: 10.0,
bottom: 10,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(150.0),
child: Image(
image: NetworkImage("${foodDetails["이미지"]}"),
width: 280,
height: 280,
fit: BoxFit.cover,
),
),
),
],
),
],
),
],
),
SizedBox(
height: 10,
),
Padding(
padding: const EdgeInsets.only(left: 260, bottom: 8),
child: Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: ElevatedButton(
onPressed: () {
launch(foodDetails['깃허브']!);
},
child: Image.network(
'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQXqDKyfbUJ3bsDc5tPovwsAHicZqq5HIMDYPvmRzpdmg&s',
width: 20,
height: 20,
fit: BoxFit.contain,
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white),
),
),
),
),
Padding(
padding: const EdgeInsets.only(right: 8),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: ElevatedButton(
onPressed: () {
launch(foodDetails['벨로그']!);
},
child: Image.network(
'https://velog.velcdn.com/images/velog/profile/9aa07f66-5fcd-41f4-84f2-91d73afcec28/green%20favicon.png',
width: 20,
height: 20,
fit: BoxFit.contain,
),
style: ButtonStyle(
backgroundColor:
MaterialStateProperty.all(Colors.white),
),
),
),
),
],
),
),
Center(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
left: 15,
),
child: Container(
height: 60,
width: 380,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular(20),
),
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 20),
child: Text(
"이름 : ${foodDetails['이름']}",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 19,
wordSpacing: 4,
),
),
),
],
),
),
SizedBox(
height: 25,
),
Center(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
left: 15,
),
child: Container(
height: 60,
width: 380,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular(20),
),
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 20),
child: Text(
"제조년월 : ${foodDetails['제조년월']}",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 19,
wordSpacing: 4,
),
),
),
],
),
),
SizedBox(
height: 25,
),
Center(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
left: 15,
),
child: Container(
height: 60,
width: 380,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular(20),
),
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 20),
child: Text(
"성분 : ${foodDetails['성분']}",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 19,
wordSpacing: 4,
),
),
),
],
),
),
SizedBox(
height: 25,
),
Center(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
left: 15,
),
child: Container(
height: 60,
width: 380,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular(20),
),
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 20),
child: Text(
"원산지 : ${foodDetails['원산지']}",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 19,
wordSpacing: 4,
),
),
),
],
),
),
SizedBox(
height: 25,
),
Center(
child: Stack(
children: [
Padding(
padding: const EdgeInsets.only(
left: 15,
),
child: Container(
height: 60,
width: 380,
decoration: new BoxDecoration(
borderRadius: new BorderRadius.all(
Radius.circular(20),
),
color: Colors.white,
),
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 50, vertical: 20),
child: Text(
"영양정보 : ${foodDetails['영양정보']}",
style: TextStyle(
fontWeight: FontWeight.w900,
fontSize: 19,
wordSpacing: 4,
),
),
),
],
),
),
SizedBox(
height: 5,
),
],
),
),
),
),
);
}
}
-editPageTwo.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'foodDetail.dart';
import 'main.dart';
import 'dart:convert';
class EditPage extends StatefulWidget {
// final Map<String, String> foodDetails;
final TextEditingController image;
final TextEditingController nameController;
final TextEditingController manufactureDateController;
final TextEditingController date;
final TextEditingController origin;
final TextEditingController nutritionalInformation;
final TextEditingController github;
final TextEditingController velog;
const EditPage({
Key? key,
// required this.foodDetails,
required this.image,
required this.nameController,
required this.manufactureDateController,
required this.date,
required this.origin,
required this.nutritionalInformation,
required this.github,
required this.velog,
required Map<String, String> foodDetails,
}) : super(key: key);
@override
State<EditPage> createState() => _EditPageState();
}
class _EditPageState extends State<EditPage> {
@override
Widget build(BuildContext context) {
var foodDetails = Provider.of<FoodDetails>(context).details;
widget.image.text = foodDetails['이미지'] ?? '';
widget.nameController.text = foodDetails['이름'] ?? '';
widget.manufactureDateController.text = foodDetails['제조년월'] ?? '';
widget.date.text = foodDetails['성분'] ?? '';
widget.origin.text = foodDetails['원산지'] ?? '';
widget.nutritionalInformation.text = foodDetails['영양정보'] ?? '';
widget.github.text = foodDetails['깃허브'] ?? '';
widget.velog.text = foodDetails['벨로그'] ?? '';
return Scaffold(
//
appBar: AppBar(
elevation: 0,
backgroundColor: Colors.white,
leading: IconButton(
onPressed: () {
setState(() {
// TextField의 값을 가져와 foodDetails를 수정합니다.
foodDetails['이름'] = widget.nameController.text;
foodDetails['제조년월'] = widget.manufactureDateController.text;
foodDetails['성분'] = widget.date.text;
foodDetails['원산지'] = widget.origin.text;
foodDetails['영양정보'] = widget.nutritionalInformation.text;
foodDetails['깃허브'] = widget.image.text;
foodDetails['벨로그'] = widget.image.text;
foodDetails['깃허브'] = widget.image.text;
foodDetails['벨로그'] = widget.image.text;
// TODO: 필요한 경우 다른 항목을 수정합니다.
});
Navigator.pop(context, foodDetails);
},
icon: Text(
"Done",
style: TextStyle(
color: Colors.redAccent,
fontWeight: FontWeight.bold,
fontSize: 15),
)),
//Done 버튼
title: Text(
'Order Memo',
style: TextStyle(
color: Colors.redAccent,
fontWeight: FontWeight.w900,
fontSize: 30,
),
),
),
body: SingleChildScrollView(
child: Column(
children: [
Container(
color: Colors.redAccent,
height: 180,
),
Column(
children: [
Stack(
children: [
Container(
color: Colors.redAccent,
height: 900,
),
Padding(
padding: const EdgeInsets.only(left: 10, bottom: 10),
child: Image(
image: NetworkImage(
'https://cdn.discordapp.com/attachments/1128561724249886777/1128965742352678932/image.png',
),
fit: BoxFit.cover,
),
),
Padding(
padding: const EdgeInsets.only(left: 320, top: 300),
child: Image(
image: NetworkImage(
'https://cdn.discordapp.com/attachments/1128561724249886777/1129003548739387392/image.png'),
width: 200,
height: 200,
),
),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 0,
vertical: 40,
),
child: Container(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 120,
vertical: 0,
),
child: Column(
children: [
TextField(
controller: widget.nameController,
decoration: InputDecoration(
labelText: '이름',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.redAccent,
),
),
),
),
TextField(
controller: widget.manufactureDateController,
decoration: InputDecoration(
labelText: '제조년월',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.redAccent,
),
),
),
),
TextField(
controller: widget.date,
decoration: InputDecoration(
labelText: '성분',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.redAccent,
),
),
),
),
TextField(
controller: widget.origin,
decoration: InputDecoration(
labelText: '원산지',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.redAccent,
),
),
),
),
TextField(
controller: widget.nutritionalInformation,
decoration: InputDecoration(
labelText: '영양정보',
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.redAccent,
),
),
),
),
],
),
),
),
),
Padding(
padding: const EdgeInsets.only(top: 290, left: 210),
child: Center(
child: IconButton(
icon: Icon(Icons.check),
iconSize: 40,
color: const Color.fromARGB(255, 47, 230, 53),
onPressed: () {
var updatedFoodDetails = {
'이미지': widget.image.text,
'이름': widget.nameController.text,
'제조년월': widget.manufactureDateController.text,
'성분': widget.date.text,
'원산지': widget.origin.text,
'영양정보': widget.nutritionalInformation.text,
'깃허브': widget.github.text,
'벨로그': widget.velog.text,
};
Provider.of<FoodDetails>(context, listen: false)
.details = updatedFoodDetails;
String json = jsonEncode(updatedFoodDetails);
print(json);
Navigator.pop(context, updatedFoodDetails);
},
),
),
),
],
),
],
),
],
),
),
);
}
}
-foodDetail.dart
import 'package:flutter/foundation.dart';
class FoodDetails extends ChangeNotifier {
void updateFoodDetails(String foodName, Map<String, String> newDetails) {
if (_foodDetailsList.containsKey(foodName)) {
_foodDetailsList[foodName] = newDetails;
}
notifyListeners();
}
Map<String, Map<String, String>> _foodDetailsList = {
"의정부부대버거A": {
'이미지':
'https://mblogthumb-phinf.pstatic.net/MjAxNzA4MjBfMTM5/MDAxNTAzMjM0MDkwNTg5.ttYjcybf_Od-SDC4LX-G_cbWjnYB2881WjrJZi5EIdsg.xtWB-23gpv-1iYusY89C5oYHkHx80E-cWm6vgbkCknwg.JPEG.jangkkoo/%EC%98%81%ED%99%94_%EA%B7%B8%EB%A0%98%EB%A6%B0_3_%EA%B0%81%EB%B3%B8_%EC%99%84%EB%A3%8C%2C_%EA%B8%B0%EC%A6%88%EB%AA%A8%EC%97%90_%EB%8C%80%ED%95%B4_%EC%95%8C%EB%A9%B4_%EB%8D%94_%EC%9E%AC%EB%AF%B8%EC%9E%88%EB%8A%94_9%EA%B0%80%EC%A7%80_%286%29.jpg?type=w800',
'이름': '조계성',
'제조년월': '1998.01.05',
'성분': 'INTJ',
'원산지': '의정부',
'영양정보': 'Omega3',
'깃허브': 'https://github.com/jakkujakku/FiveGuys',
'벨로그': "https://velog.io/@cheshire0105/about",
},
"의정부부대버거B": {
'이미지': 'https://photo.cosplayfu.com/character/mini/24623_286445.jpg',
'이름': '박철우',
'제조년월': '1993.04.18',
'성분': 'INTP',
'원산지': '의정부',
'영양정보': 'Carbohyrate',
'깃허브': 'https://github.com/jakkujakku/FiveGuys',
'벨로그': 'https://velog.io/@churoo',
},
"대구따로버거": {
'이미지': 'https://avatars.githubusercontent.com/u/89556301?v=4',
'이름': '김준우',
'제조년월': '1998.06.29',
'성분': 'ENTJ',
'원산지': '대구',
'영양정보': 'Iron content',
'깃허브': 'https://github.com/jakkujakku/FiveGuys',
'벨로그': "https://velog.io/@jakkujakku98",
},
"남양주닭갈비버거": {
'이미지':
'https://www.thedrive.co.kr/news/data/20230418/p1065613542337446_942_thum.PNG',
'이름': '이시영',
'제조년월': '1989.04.15',
'성분': 'ENFJ',
'원산지': '남양주',
'영양정보': 'Hemoglobin',
'깃허브': 'https://github.com/jakkujakku/FiveGuys',
'벨로그': 'https://velog.io/@code_dang',
},
"수원갈비버거": {
'이미지':
'https://static.wikia.nocookie.net/pokemon/images/d/d0/%EA%BC%AC%EB%A7%88%EB%8F%8C_%EA%B3%B5%EC%8B%9D_%EC%9D%BC%EB%9F%AC%EC%8A%A4%ED%8A%B8.png/revision/latest?cb=20170405014701&path-prefix=ko',
'이름': '조재민',
'제조년월': '1996.10.25',
'성분': 'INFP',
'원산지': '수원',
'영양정보': 'Protein',
'깃허브': 'https://github.com/jakkujakku/FiveGuys',
'벨로그': 'https://velog.io/@user2rum',
},
// Add more food details here...
};
Map<String, String> _details = {};
Map<String, String> get details => _details;
set details(Map<String, String> newDetails) {
_details = newDetails;
notifyListeners(); // 상태가 변경되었음을 알림
}
void setFoodDetails(String foodName) {
if (_foodDetailsList.containsKey(foodName)) {
_details = _foodDetailsList[foodName]!;
} else {
_details = {
'이름': '기본음식',
'제조년월': '2023.01.01',
'성분': '기본맛',
'영양정보': '기본',
};
}
notifyListeners(); // 상태가 변경되었음을 알림
}
}