본문 바로가기
플러터/Card UI 만들기

[Card UI] Card Section / Icons and Transforms / Reusable Card 만들기

by zldn 2024. 3. 17.

1. Card Section 만들기

import 'package:flutter/material.dart';

import 'button.dart';

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

class App extends StatelessWidget{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFF181818),
        body: Padding(
          padding: EdgeInsets.symmetric(horizontal: 20),

          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children:[
              SizedBox(
                height: 80,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children:[
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children:[
                      Text('Hey, Selena',
                          style: TextStyle(
                              color: Colors.white,
                              fontSize: 38,
                              fontWeight: FontWeight.w600
                          )
                      ),
                      Text('Welcome back',
                          style: TextStyle(
                              color: Colors.white.withOpacity(0.8), //Color.fromRGB(255,255,255,0.8) 이렇게 적어도 됨
                              fontSize: 18
                          )
                      ),
                    ],
                  )
                ],
              ),
              SizedBox(
                height: 120,
              ),
              Text(
                'Total Balance',
                style: TextStyle(
                  fontSize: 22,
                  color: Colors.white.withOpacity(0.8),
                ),
              ),
              SizedBox(
                height: 5,
              ),
              Text(
                '\$5 194 482',
                style: TextStyle(
                  fontSize: 48,
                  fontWeight: FontWeight.w600,
                  color: Colors.white,
                ),
              ),
              SizedBox(
                height: 20,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween, //버튼들 사이에 공간 두기
                children: [
                  Button(text: 'Transfer',
                    bgColor: Color(0xFFF1B33B),
                    textColor: Colors.black,
                  ),
                  Button(text: 'Request',
                    bgColor: Color(0xFF1F2123),
                    textColor: Colors.white,
                  ),
                ],
              ),
              SizedBox(height: 100,
              ),
              Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children:[
                  Text('Wallets',
                      style:TextStyle(
                        color:Colors.white,
                        fontSize:36,
                        fontWeight: FontWeight.w600,
                      )),
                  Text('View All',
                    style: TextStyle(
                      color: Colors.white.withOpacity(0.8),
                      fontSize: 18,
                    ),
                  ),
                ],
              ),
              SizedBox(
                height:20,
              ),
              Container(
                decoration: BoxDecoration(
                  color:Color(0xFF1F2123),
                  borderRadius: BorderRadius.circular(25),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(30
                  ),
                  child: Row(
                    children:[
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children:[
                          Text('Euro',
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 32,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          SizedBox(
                            height:10,
                          ),
                          Row(
                            children:[
                              Text('6 428',
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 20,
                                ),
                              ),
                              SizedBox(
                                width: 5,
                              ),
                              Text('EUR',
                                style: TextStyle(
                                  color: Colors.white.withOpacity(0.8),
                                  fontSize: 20,
                                ),),
                            ],
                          )
                        ],
                      )
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

*실행화면

>> 카드 부분이 추가된 것을 볼 수 있다.

 

 

2. Card Section에 Icon과 Transform 사용하기

>> Icon = 플러터에서 아이콘은 별도의 다운로드 없이 icon 위젯을 사용할 수 있다.

 

Transform.scale(
         //아이콘의 크기는 커지지만 박스의 크기는 안 바뀜(카드 밖으로 넘치게 할 수 있음)
	scale:2.2,
    child: Transform.translate(
    	offset: Offset(-5,12), //아이콘이 카드 밖으로 떨어지도록 할 수 있음
       	child: Icon(
        	Icons.euro_rounded,
           	color: Colors.white,
            size: 98,
        ),    
    ),
),
=====================================================================================================

clipBehavior: Clip.hardEdge, //카드 밖으로 나간 아이콘을 잘라냄

 

>>전체코드

//전체코드
import 'package:flutter/material.dart';
import 'button.dart';

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

class App extends StatelessWidget{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFF181818),
        body: Padding(
          padding: EdgeInsets.symmetric(horizontal: 20),

          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children:[
              SizedBox(
                height: 80,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children:[
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children:[
                      Text('Hey, Selena',
                          style: TextStyle(
                              color: Colors.white,
                              fontSize: 38,
                              fontWeight: FontWeight.w600
                          )
                      ),
                      Text('Welcome back',
                          style: TextStyle(
                              color: Colors.white.withOpacity(0.8), //Color.fromRGB(255,255,255,0.8) 이렇게 적어도 됨
                              fontSize: 18
                          )
                      ),
                    ],
                  )
                ],
              ),
              SizedBox(
                height: 120,
              ),
              Text(
                'Total Balance',
                style: TextStyle(
                  fontSize: 22,
                  color: Colors.white.withOpacity(0.8),
                ),
              ),
              SizedBox(
                height: 5,
              ),
              Text(
                '\$5 194 482',
                style: TextStyle(
                  fontSize: 48,
                  fontWeight: FontWeight.w600,
                  color: Colors.white,
                ),
              ),
              SizedBox(
                height: 20,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween, //버튼들 사이에 공간 두기
                children: [
                  Button(text: 'Transfer',
                    bgColor: Color(0xFFF1B33B),
                    textColor: Colors.black,
                  ),
                  Button(text: 'Request',
                    bgColor: Color(0xFF1F2123),
                    textColor: Colors.white,
                  ),
                ],
              ),
              SizedBox(height: 100,
              ),
              Row(
                crossAxisAlignment: CrossAxisAlignment.end,
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children:[
                  Text('Wallets',
                      style:TextStyle(
                        color:Colors.white,
                        fontSize:36,
                        fontWeight: FontWeight.w600,
                      )),
                  Text('View All',
                    style: TextStyle(
                      color: Colors.white.withOpacity(0.8),
                      fontSize: 18,
                    ),
                  ),
                ],
              ),
              SizedBox(
                height:20,
              ),
              Container(
                clipBehavior: Clip.hardEdge, //카드 밖으로 나간 아이콘을 잘라냄
                decoration: BoxDecoration(
                  color:Color(0xFF1F2123),
                  borderRadius: BorderRadius.circular(25),
                ),
                child: Padding(
                  padding: const EdgeInsets.all(30
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children:[
                      Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children:[
                          Text('Euro',
                            style: TextStyle(
                              color: Colors.white,
                              fontSize: 32,
                              fontWeight: FontWeight.w600,
                            ),
                          ),
                          SizedBox(
                            height:10,
                          ),
                          Row(
                            children:[
                              Text('6 428',
                                style: TextStyle(
                                  color: Colors.white,
                                  fontSize: 20,
                                ),
                              ),
                              SizedBox(
                                width: 5,
                              ),
                              Text('EUR',
                                style: TextStyle(
                                  color: Colors.white.withOpacity(0.8),
                                  fontSize: 20,
                                ),),
                            ],
                          )
                        ],
                      ),

                      Transform.scale(
                        //아이콘의 크기는 커지지만 박스의 크기는 안 바뀜(카드 밖으로 넘치게 할 수 있음)
                        scale:2.2,
                        child: Transform.translate(
                          offset: Offset(-5,12), //아이콘이 카드 밖으로 떨어지도록 할 수 있음
                          child: Icon(Icons.euro_rounded,
                            color: Colors.white,
                            size: 98,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

*실행화면

>> 카드에 아이콘이 추가된 모습을 볼 수 있다.

 

 

 

 

3. 카드를 한개만 만들것이 아니니까 reusable widget으로 만들기

: 카드부분을 따로 떼서 card.dart에 넣도록 한다.

 

>> 메인.dart

//메인

import 'package:flutter/material.dart';
import 'button.dart';
import 'card.dart';

class Player{
  String name;
  Player({required this.name});
}

void main() {
  var jiwoo = Player(name: "jiwoo");
  runApp(App());
}

class App extends StatelessWidget{

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Color(0xFF181818),
        body: SingleChildScrollView( //화면에 오버플로우가 발생했을때 스크롤 할 수 있도록 해주는 기능
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 20),

            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children:[
                SizedBox(
                  height: 30,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.end,
                  children:[
                    Column(
                      crossAxisAlignment: CrossAxisAlignment.end,
                      children:[
                        Text('Hey, Selena',
                            style: TextStyle(
                                color: Colors.white,
                                fontSize: 38,
                                fontWeight: FontWeight.w600
                            )
                        ),
                        Text('Welcome back',
                            style: TextStyle(
                                color: Colors.white.withOpacity(0.8), //Color.fromRGB(255,255,255,0.8) 이렇게 적어도 됨
                                fontSize: 18
                            )
                        ),
                      ],
                    )
                  ],
                ),
                SizedBox(
                  height: 40,
                ),
                Text(
                  'Total Balance',
                  style: TextStyle(
                    fontSize: 22,
                    color: Colors.white.withOpacity(0.8),
                  ),
                ),
                SizedBox(
                  height: 5,
                ),
                Text(
                  '\$5 194 482',
                  style: TextStyle(
                    fontSize: 48,
                    fontWeight: FontWeight.w600,
                    color: Colors.white,
                  ),
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween, //버튼들 사이에 공간 두기
                  children: [
                    Button(text: 'Transfer',
                      bgColor: Color(0xFFF1B33B),
                      textColor: Colors.black,
                    ),
                    Button(text: 'Request',
                      bgColor: Color(0xFF1F2123),
                      textColor: Colors.white,
                    ),
                  ],
                ),
                SizedBox(height: 50,
                ),
                Row(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children:[
                    Text('Wallets',
                        style:TextStyle(
                          color:Colors.white,
                          fontSize:36,
                          fontWeight: FontWeight.w600,
                        )),
                    Text('View All',
                      style: TextStyle(
                        color: Colors.white.withOpacity(0.8),
                        fontSize: 18,
                      ),
                    ),
                  ],
                ),
                SizedBox(
                  height:20,
                ),
                CurrencyCard(
                  name:'Euro',
                  code:'EUR',
                  amount: '6 428',
                  icon: Icons.euro_rounded,
                  isInverted: false,
                ),
                Transform.translate(
                  offset: Offset(0,-20), //카드들을 포개서 두기 위해서
                  child: CurrencyCard(
                    name:'Bitcoin',
                    code:'BTC',
                    amount: '9 785',
                    icon: Icons.currency_bitcoin,
                    isInverted: true,
                  ),
                ),
                Transform.translate(
                  offset: Offset(0,-40),  //카드들을 포개서 두기 위해서
                  child: CurrencyCard(
                    name:'Dollar',
                    code:'USA',
                    amount: '428',
                    icon: Icons.attach_money_outlined,
                    isInverted: false,
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

 

>>card.dart

//card class

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class CurrencyCard extends StatelessWidget{

  final String name, code, amount;
  final IconData icon;
  final bool isInverted;

  final _blackColor = const Color(0xFF1F2123);

  const CurrencyCard({
    super.key,
    required this.name,
    required this.code,
    required this.amount,
    required this.icon,
    required this.isInverted,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      clipBehavior: Clip.hardEdge, //컨테이너(카드) 밖 부분을 잘라내는 역할
      decoration: BoxDecoration(
        color: isInverted ? Colors.white :_blackColor,
        borderRadius: BorderRadius.circular(25),
      ),
      child: Padding(
        padding: const EdgeInsets.all(30
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children:[
            Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children:[
                Text(name,
                  style: TextStyle(
                    color: isInverted? _blackColor: Colors.white,
                    fontSize: 32,
                    fontWeight: FontWeight.w600,
                  ),
                ),
                SizedBox(
                  height:10,
                ),
                Row(
                  children:[
                    Text(amount,
                      style: TextStyle(
                        color: isInverted? _blackColor:Colors.white,
                        fontSize: 20,
                      ),
                    ),
                    SizedBox(
                      width: 5,
                    ),
                    Text(code,
                      style: TextStyle(
                        color: isInverted? _blackColor: Colors.white.withOpacity(0.8),
                        fontSize: 20,
                      ),),
                  ],
                )
              ],
            ),

            Transform.scale(
              scale:2.2, //부모와 관계없이 크기를 키움
              child: Transform.translate(
                offset: Offset(-5,12), //아이콘을 어디에 위치 시킬 것인지 결정
                child: Icon(
                  icon, //아이콘의 모양은 미리보기로 보기 가능
                  color: isInverted? _blackColor:Colors.white,
                  size: 98,
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }

}

 

 

*실행화면

>>카드가 여러개 생긴 것을 볼 수 있다.

'플러터 > Card UI 만들기' 카테고리의 다른 글

[Card UI] 전체코드  (6) 2024.03.17
[Card UI] Button Section / Reusable Button  (2) 2024.03.17
[Card UI] Head 부분 만들기  (0) 2024.03.17