ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 키오스크 앱 업그레이드 ver3
    카테고리 없음 2023. 2. 21. 15:38

    기존의 키오스크앱을 활용하여 다음의 결과물을 제작할 수 있도록 합니다.

    • 음식리스트는 다음의 API 주소에서 가져올 수 있습니다.
    • 음식을 클릭하면, 주문리스트에 저장함과 동시에 앱 데이터에도 저장될 수 있도록 합니다.
    • 주문 리스트의 Chip 의 삭제버튼을 누르면 앱 데이터에도 새로 저장될 수 있도록 합니다.
    • 이 때, 앱 데이터를 저장하는 패키지는 shared_preferences 를 사용하여 해결합니다.
    • 해당과제는 새로고침을 해도 주문리스트가 남아있는지가 핵심입니다.

    pubspec.yaml

    dependencies:
      flutter:
        sdk: flutter
    
      cupertino_icons: ^1.0.2
      shared_preferences: ^2.0.17
      dio: ^5.0.0

    MainPage.dart

    import 'package:assigment20/adminpage.dart';
    import 'package:flutter/material.dart';
    import 'package:shared_preferences/shared_preferences.dart';
    import 'package:dio/dio.dart';
    
    class MainPage extends StatefulWidget {
      const MainPage({super.key});
    
      @override
      State<MainPage> createState() => _MainPageState();
    }
    
    class _MainPageState extends State<MainPage> {
      List<String> order = [];
      var dio = Dio();
      var url = 'http://52.79.115.43:8090/api/collections/options/records';
      SharedPreferences? prefs;      객체
    
      Future getData() async {
        var res = await dio.get(url);
        return res.data["items"];
      }
    
      @override
      void initState() {            //한번만 실행되는 초기화함수
        super.initState();
        initPreferences(); 
      }
    
      void initPreferences() async {          //저장하는 함수
        prefs = await SharedPreferences.getInstance();       //initState에 의해 prefs에 새로운값이 들어감
        if (prefs != null) {
          order = prefs!.getStringList('order') ?? [];
          setState(() {});
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: GestureDetector(
              onDoubleTap: () {
                Navigator.push(context,
                    MaterialPageRoute(builder: ((context) => AdminPage())));
              },
              child: Text('분식왕 이테디 주문하기'),
            ),
            centerTitle: true,
            backgroundColor: Colors.transparent,
            foregroundColor: Colors.black,
            elevation: 0,
          ),
          body: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
            Text(
              '주문 리스트',
              style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
            ),
            order.isEmpty
                ? Center(child: (Text('주문한 메뉴가 없습니다.')))
                : Wrap(
                    spacing: 3,
                    runSpacing: 3,
                    children: order
                        .map((e) => Chip(
                            label: Text(e),
                            onDeleted: () {
                              setState(() {
                                order.remove(e);
                              });
                            }))
                        .toList()),
            Padding(
              padding: const EdgeInsets.only(top: 8),
              child: Text(
                '음식',
                style: TextStyle(fontSize: 30, fontWeight: FontWeight.bold),
              ),
            ),
            Expanded(
              child: FutureBuilder(
                future: getData(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    return GridView.builder(
                      itemCount: snapshot.data!.length,
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 3),
                      itemBuilder: (context, index) {
                        return GestureDetector(
                          onTap: () {
                            order.add(snapshot.data[index]['menu']);
                            if (prefs != null) {
                              prefs!.setStringList('order', order);
                            }
                            setState(() {});
                          },
                          child: Card(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Expanded(
                                    child: Image(
                                  image: NetworkImage(
                                      snapshot.data[index]['imageUrl']),
                                  width: MediaQuery.of(context).size.width,
                                  fit: BoxFit.cover,
                                )),
                                Text(snapshot.data[index]["menu"]),
                                Text(
                                  '[담기]',
                                  style: TextStyle(color: Colors.black),
                                ),
                              ],
                            ),
                          ),
                        );
                      },
                    );
                  }
                  return CircularProgressIndicator();
                },
              ),
            ),
          ]),
          floatingActionButton: AnimatedOpacity(
            opacity: order.isNotEmpty ? 1 : 0,
            duration: Duration(seconds: 1),
            child: FloatingActionButton.extended(
              onPressed: () {},
              label: Text('결제하기'),
            ),
          ),
          floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
        );
      }
    }

     

    메뉴를 추가하고 새로고침하면 마지막에 추가한 메뉴는 없어지길래 팀원인 관우님께 물어봐서 해결했습니다.

    return GestureDetector(
                          onTap: () {
                            order.add(snapshot.data[index]['menu']);
                            if (prefs != null) {
                              prefs!.setStringList('order', order);
                            }
                            setState(() {});
                          },

    첨엔 오더와 저장부분 순서를 별 생각없이 바꿔서 코드를 써서 안됐는데

    관우님 말로는 마지막 메뉴를 order에 넣고 로컬에 저장해야하는데 로컬에 저장하고 order에 넣으니까 마지막 메뉴는 저장 안되고 order에만 들어간다고 말해주셨습니다. 다음에도 도움이 필요하면 관우님께...ㅎ

     

    ver2에서 쓴 AdminPage는 그대로..

    import 'package:flutter/material.dart';
    
    class AdminPage extends StatelessWidget {
      const AdminPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              centerTitle: true,
              title: Text('Admin Page'),
              leading: GestureDetector(
                  onTap: () {
                    Navigator.pop(context);
                  },
                  child: Icon(Icons.arrow_back_ios_new)),
            ),
            body: SafeArea(
                child: Column(
              children: [
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Text('메뉴 추가'),
                ),
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Text('메뉴 삭제'),
                ),
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Text('메뉴 수정'),
                ),
              ],
            )),
          ),
        );
      }
    }

    Android Emulator - Pixel_6_Pro_API_27_5554 2023-02-21 15-35-30.mp4
    8.56MB

Designed by Tistory.