쇼핑 카트 앱 만들어 보기

 

목차

    1. 요구 사항

    git code
     

    flutter-book/flutter_shoppingcart at master · flutter-coder/flutter-book

    Contribute to flutter-coder/flutter-book development by creating an account on GitHub.

    github.com

    작업 순서

    constants.dart 파일 작업
    theme.dart 파일 작업
    .. header.dart
    … details.dart

    2. constants.dart 파일 작업

    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); // 활성화 버튼 색

    3. theme.dart 파일 작업

    import 'package:flutter/material.dart';
    import 'package:flutter_shoppingcart/constants.dart';
    
    ThemeData theme() {
      return ThemeData(
        primarySwatch: kPrimaryColor,
        scaffoldBackgroundColor: kPrimaryColor,
      );
    }

    4. ShoppingcartHeader 위젯

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';
    import 'package:flutter_shoppingcart/constants.dart';
    
    class ShoppingcartHeader extends StatefulWidget {
      const ShoppingcartHeader({super.key});
    
      @override
      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',
      ];
    
      @override
      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),
            ],
          ),
        );
      }
    
      Widget _buildHeaderSelectorButton(int id, IconData mIcon) {
        return Container(
          width: 70,
          height: 70,
          decoration: BoxDecoration(
              color: id == selectedId ? kAccentColor : kSecondaryColor,
              borderRadius: BorderRadius.circular(20.0)),
          child: IconButton(
            onPressed: () {
              setState(() {
                selectedId = id;
              });
            },
            icon: Icon(mIcon),
          ),
        );
      }
    }

    5. ShoppingcartDetail 위젯

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_shoppingcart/constants.dart';
    
    class ShoppingcartDetail extends StatelessWidget {
      const ShoppingcartDetail({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Container(
          decoration: BoxDecoration(
              color: Colors.white, borderRadius: BorderRadius.circular(40.0)),
          child: Padding(
            padding: const EdgeInsets.all(30.0),
            child: Column(
              children: [
                _buildDetailNameAndPrice(),
                _buildDetailRatingAndReviewCount(),
                _buildDetailColorOptions(),
                _buildDetailButton(context),
              ],
            ),
          ),
        );
      } // end of build
    
      Widget _buildDetailNameAndPrice() {
        return const Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            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 const Padding(
          padding: EdgeInsets.only(bottom: 20.0),
          child: Row(
            children: [
              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),
              // row 위젯 기준으로 남은 여백 다 차지
              Spacer(),
              Text('Review '),
              Text(
                '(26)',
                style: TextStyle(color: Colors.blue),
              )
            ],
          ),
        );
      }
    
      Widget _buildDetailColorOptions() {
        return Padding(
          padding: const EdgeInsets.only(bottom: 20),
          child: Column(
            children: [
              const Text('Color Options'),
              const SizedBox(height: 10),
              Row(
                children: [
                  // 재사용을 위해 함수로 설계
                  _buildDetailIcons(Colors.black),
                  _buildDetailIcons(Colors.green),
                  _buildDetailIcons(Colors.orange),
                  _buildDetailIcons(Colors.grey),
                  _buildDetailIcons(Colors.white),
                ],
              )
            ],
          ),
        );
      }
    
      // 여러번 추후 호출 해야 한다.
      Widget _buildDetailIcons(Color mColor) {
        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,
                  ),
                ),
              )
            ],
          ),
        );
      }
    
      Widget _buildDetailButton(BuildContext context) {
        return Align(
          child: TextButton(
            onPressed: () {
              // alert dialog 사용법
              // 플랫폼 별 준비,
              // 1.
              showCupertinoDialog(
                context: context,
                builder: (context) {
                  return CupertinoAlertDialog(
                    title: Text('장바구니에 담으시겠습니까?'),
                    actions: [
                      CupertinoDialogAction(
                          onPressed: () {
                            // 플러터 프레임워크가
                            // 화면간 이동시에 위젯들을
                            // 스택구조로 관리해주는 객체이다.
                            Navigator.pop(context);
                          },
                          child: Text('확인')),
                    ],
                  );
                },
              );
            },
            style: TextButton.styleFrom(
                backgroundColor: kAccentColor,
                minimumSize: const Size(300, 50),
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(15),
                )),
            child: const Text(
              'Add to Cart',
              style: TextStyle(
                color: Colors.white,
              ),
            ),
          ),
        );
      }
    }

     

    6. main.dart

    import 'package:flutter/material.dart';
    import 'package:flutter_shoppingcart/mvvm/view/shoppingcart_detail.dart';
    import 'package:flutter_shoppingcart/mvvm/view/shoppingcart_header.dart';
    import 'package:flutter_shoppingcart/mvvm/view_models/item_view_model.dart';
    import 'package:flutter_shoppingcart/theme.dart';
    import 'package:provider/provider.dart';
    
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return  ChangeNotifierProvider<ItemViewModel>(
          create: (_) => ItemViewModel(),
          child: MaterialApp(
            theme: theme(),
            home: SafeArea(
              child: ShoppingCartPage(),
            ),
          ),
        );
      }
    }
    
    class ShoppingCartPage extends StatelessWidget {
      const ShoppingCartPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: _buildShoppingCartAppBar(),
          body: Column(
            children: [
              ShoppingcartHeader(),
              Expanded(child: ShoppingcartDetail()),
            ],
          ),
        );
      }
    
      // private 메서드 만들어 보기
    
      AppBar _buildShoppingCartAppBar() {
        return AppBar(
          leading: IconButton(
            onPressed: () {},
            icon: const Icon(Icons.arrow_back),
          ),
          actions: [
            IconButton(
              onPressed: () {},
              icon: const Icon(Icons.shopping_cart),
            ),
            const SizedBox(width: 16),
          ],
          elevation: 0.0,
        );
      }
    }

    목차로 돌아가기

     

    'Flutter > Flutter UI 프레임워크' 카테고리의 다른 글

    Dio 통신 연습  (0) 2024.11.13
    BottomSheet 위젯 & TabBar 위젯  (0) 2024.11.13
    GridView 위젯 & PageView 위젯  (0) 2024.11.13
    ListView 사용법과 주요 property  (0) 2024.11.13
    Form 위젯  (0) 2024.11.13