Flutter

[Flutter] ์‡ผํ•‘ ์นดํŠธ ์•ฑ ๋งŒ๋“ค์–ด ๋ณด๊ธฐ

๋ฏธ๋กœ910 2024. 11. 11. 14:59


๐Ÿ’ก ์ž‘์—… ์ˆœ์„œ

constants.dart ํŒŒ์ผ ์ž‘์—…
theme.dart ํŒŒ์ผ ์ž‘์—…
.. header.dart
… details.dart

 

๊ตฌ์กฐ

 

constants.dart ํŒŒ์ผ ์ž‘์—…
import 'package:flutter/material.dart';

// 3๊ฐœ ์ƒ์ˆ˜ ๋ฏธ๋ฆฌ ์ •์˜ (์žฌํ™œ์šฉ)

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); // ํ™œ์„ฑํ™” ๋ฒ„ํŠผ ์ƒ‰

 

theme.dart ํŒŒ์ผ ์ž‘์—…
import 'package:flutter/material.dart';
import 'package:flutter_shoppingcart/constants.dart';

ThemeData theme() {
  return ThemeData(
    primarySwatch: kPrimaryColor,
    scaffoldBackgroundColor: kPrimaryColor,
  );
}

 

ํ—ค๋”

main.dart ํŒŒ์ผ
import 'package:flutter/material.dart';
import 'package:flutter_shoppingcart/components/shoppingcart_detail.dart';
import 'package:flutter_shoppingcart/components/shoppingcart_header.dart';
import 'package:flutter_shoppingcart/theme.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return 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 -> ํ™•์žฅ
          Expanded(child: ShoppingcartDetail())
        ],
      ),
    );
  }

  // private ๋ฉ”์„œ๋“œ ๋งŒ๋“ค์–ด ๋ณด๊ธฐ
  AppBar _buildShoppingCartAppBar() {
    return AppBar(
      leading: IconButton(
        onPressed: () {},
        icon: Icon(Icons.arrow_back),
      ),
      actions: [
        IconButton(
          onPressed: () {},
          icon: Icon(Icons.shopping_cart),
        ),
        // ์—ฌ๋ฐฑ
        SizedBox(width: 16),
      ],
      elevation: 0.0,
    );
  }
}

 

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 = 1;
  // ์ด๋ฏธ์ง€ ๋ชฉ๋ก
  List<String> selectedPic = [
    'assets/p1.jpeg',
    'assets/p2.jpeg',
    'assets/p3.jpeg',
    'assets/p4.jpeg',
  ];

  // StatefulWidget -> ๋™์  (๋ฒ„ํŠผ ํด๋ฆญํ–ˆ์„ ๋•Œ UI ๋ณ€๊ฒฝ)
  
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        _buildHeaderPic(),
        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 _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),
        ],
      ),
    );
  }

  // ID -> ๊ณ ์œ id, mIcon -> ๋ฒ„ํŠผ ์•„์ด์ฝ˜
  // Icons.arrow_back -> IconData
  Widget _buildHeaderSelectorButton(int id, IconData mIcon){
    return Container(
      width: 70,
      height: 70,
      decoration: BoxDecoration(
        color: id == selectedId ? kAccentColor : kSecondaryColor,
        borderRadius: BorderRadius.circular(20.0),
      ),
      // ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ -> IconButton
      child: IconButton(
        onPressed: () {
          setState(() {
            selectedId = id; // ์žฌ๋ Œ๋”๋ง
          });
        },
        icon: Icon(mIcon),
      ),
    );
  }


} // end of _ShoppingcartHeaderState

 

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 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 Padding(
      padding: const 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.0),
      child: Column(
        children: [
          Text('Color Options'),
          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
          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. showDialog ํ˜ธ์ถœ
          // 2. iOS -> showCupertinoDialog ํ•จ์ˆ˜
          showCupertinoDialog(
              context: context,
              builder: (context) {
                return CupertinoAlertDialog(
                  actions: [
                    CupertinoDialogAction(
                      child: Text('ํ™•์ธ'),
                      onPressed: () {
                        // Navigator --> ํ”Œ๋Ÿฌํ„ฐ ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€
                        // ํ™”๋ฉด ๊ฐ„์— ์ด๋™์‹œ์— ์œ„์ ฏ๋“ค์„
                        // ์Šคํƒ ๊ตฌ์กฐ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๊ฐ์ฒด์ด๋‹ค.
                        Navigator.pop(context);
                      },
                    ),
                  ],
                );
              });
        },
        style: TextButton.styleFrom(
          backgroundColor: kAccentColor,
          minimumSize: Size(300, 50),
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
        ),
        child: Text(
          'Add to Cart',
          style: TextStyle(
            color: Colors.white,
          ),
        ),
      ),
    );
  }
}

 

์‹คํ–‰ ํ™”๋ฉด______

'Flutter' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[Flutter] TabBar ์œ„์ ฏ  (0) 2024.11.12
[Flutter] BottomSheet ์œ„์ ฏ  (0) 2024.11.12
[Flutter] PageView ์œ„์ ฏ  (0) 2024.11.11
[Flutter] GridView ์œ„์ ฏ  (1) 2024.11.11
[Flutter] ListView ์‚ฌ์šฉ๋ฒ•๊ณผ ์ฃผ์š” property  (2) 2024.11.11