[스파르타 내일배움캠프 Swift]iOS 앱 개발 7기 4일차 - 2023. 07. 13

조재민·2023년 7월 14일
0

오늘은 그동안 작성한 코드를 수정하며 최종 마무리를 지었다.

-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(); // 상태가 변경되었음을 알림
  }
}
profile
“누군가는 너를 사랑하고 있다.”

0개의 댓글

Powered by GraphCDN, the GraphQL CDN