매일 땡기는 마라 코딩

[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 4일차 과제 - 키오스크 앱 본문

Flutter

[9주 완성 프로젝트 캠프 : 플러터(유데미x스나이퍼팩토리)] 4일차 과제 - 키오스크 앱

cmkoi1 2023. 10. 22. 22:17

요구사항

  1. 음식을 누르면 주문 리스트에 담기는 키오스크앱을 만들어봅니다.
  2. 음식이미지는 자유이며, 필요한 경우 위에 첨부된 파일을 이용하여도 됩니다.
  3. 하단에 떠있는 버튼을 누르면 지금까지 주문된 주문 리스트를 초기화합니다.
  4. 하단에 떠있는 버튼은 정중앙의 하단, 넓게 펴진 형태로 [ 초기화하기 ] 텍스트를 포함합니다.
  5. 음식이 보여지는 것은 [갤러리] 형태로 보여지게 하며, 검색을 통해 해결합니다.
  6. 그 외 UI 디자인은 자유입니다.

 

사전 지식

 

 

코드

main.dart

import 'package:assignment2/OptionCard.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

final foodList = {
  "list": [
    {"image": "assets/option_kimbap.png", "name": "김밥"},
  ]
};

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List myMenu = [];

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.white,
          foregroundColor: Colors.black,
          elevation: 0,
          title: Text('분식왕 이테디 주문하기'),
        ),
        body: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              '주문 리스트',
              style: TextStyle(
                fontSize: 28,
                fontWeight: FontWeight.bold,
              ),
            ),
            Text(myMenu.toString()),
            SizedBox(height: 8),
            Text(
              '음식',
              style: TextStyle(
                fontSize: 28,
                fontWeight: FontWeight.bold,
              ),
            ),
            Expanded(
              child: GridView(
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 3,
                ),
                children: [
                  InkWell(
                    onTap: () {
                      myMenu.add('떡볶이');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '떡볶이',
                      imgUrl: 'assets/option_bokki.png',
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      myMenu.add('맥주');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '맥주',
                      imgUrl: 'assets/option_beer.png',
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      myMenu.add('김밥');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '김밥',
                      imgUrl: 'assets/option_kimbap.png',
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      myMenu.add('오므라이스');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '오므라이스',
                      imgUrl: 'assets/option_omurice.png',
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      myMenu.add('돈까스');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '돈까스',
                      imgUrl: 'assets/option_pork_cutlets.png',
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      myMenu.add('라면');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '라면',
                      imgUrl: 'assets/option_ramen.png',
                    ),
                  ),
                  InkWell(
                    onTap: () {
                      myMenu.add('우동');
                      setState(() {});
                    },
                    child: OptionCard(
                      foodName: '우동',
                      imgUrl: 'assets/option_udon.png',
                    ),
                  ),
                ],
              ),
            )
          ],
        ),
        floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
        floatingActionButton: FloatingActionButton.extended(
          onPressed: () {
            myMenu = [];
            setState(() {});
          },
          label: Text('초기화하기'),
        ),
      ),
    );
  }
}

 

OptionCard.dart

import 'package:flutter/material.dart';

class OptionCard extends StatelessWidget {
  const OptionCard({super.key, required this.imgUrl, required this.foodName});

  final String imgUrl;
  final String foodName;

  @override
  Widget build(BuildContext context) {
    return Card(
      margin: EdgeInsets.all(4),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Expanded(
            child: Image.asset(
              imgUrl,
              fit: BoxFit.cover,
            ),
          ),
          Text(foodName),
          Text('[담기]'),
        ],
      ),
    );
  }
}

 

 

결과

 

회고

플러터를 사용하면 사용할 수록 애니메이션이나 테마가 기본적으로 굉장히 잘 갖추어져 있어서, 패키지를 많이 사용하지 않아도 괜찮은 앱을 만들 수 있겠다는 생각이 든다. 눈에 보이는 결과가 만족스러우니 흥미가 붙는 것 같다.

 

갤러리를 만들 수 있는 GridView를 처음 접하게 되었는데, 공식 문서가 영어로 되어 있으니 괜히 거부감이 든다 ㅎ... 공식 문서를 보는 연습도 하면 좋을 것 같다.

 

근데 자꾸 이것저것 찾아보다 늦게 자게 돼서,,, 흥미를 가지는 것은 좋으나 건강 잘 챙길 것.

 

참고 자료

 

 

 

본 후기는 유데미-스나이퍼팩토리 9주 완성 프로젝트캠프 학습 일지 후기로 작성 되었습니다.

 

#유데미 #udemy #스나이퍼팩토리 #웅진씽크빅 #인사이드아웃 #IT개발캠프 #개발자부트캠프 #웹개발 #앱개발 #플러터 #flutter #개발 #안드로이드 #ios #단기캠프

728x90