나만의 개발노트

[Flutter] flutter로 UI 구성해보기 본문

[Flutter]/[Flutter]

[Flutter] flutter로 UI 구성해보기

노트포미 2024. 7. 19. 01:01

[문제]

 

- 왼쪽 이미지와 같은 형태로 UI 구성해보기

*참고 페이지 : https://dribbble.com/shots/19858341-Finnancial-Mobile-IOS-App

 

<hint>

사용한 것들

- Scaffold

- Padding

- EdgeInsets

- Column, Row

- CrossAxisAlignment, mainAxisAllignment

- SizeBox

- Text

- Icons

- withOpacity

- clipBehavior : 테두리 자르기

- Transform.translate : 위치 변경

- Transform.scale : 크기 변경

- 나만의 Button 위젯

- 나만의 CurrencyCard 위젯

 

 

 

 

 

 


[정답 코드]

#main.dart 코드

import 'package:flutter/material.dart';
import 'package:toonflix/widgets/button.dart';
import 'package:toonflix/widgets/currency_card.dart';

const _blackColor = Color(0xFF1F2123);

void main() {
  runApp(const App()); //App Widget는 root이 되어야 한다
}

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

  //StatelessWidget를 상속받았으면 build()반드시 필요 -> build()의 return Widget이 UI가 됨
  @override
  Widget build(BuildContext context) {
    //Widget 형식 return
    return MaterialApp(
      home: Scaffold(
        backgroundColor: const Color(0xFF181818),
        body: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 30),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              const SizedBox(
                height: 60,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  Column(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      const Text(
                        'Hey, Mokjak',
                        style: TextStyle(
                            fontSize: 23,
                            color: Colors.white,
                            fontWeight: FontWeight.bold),
                      ),
                      Text(
                        'Welcome back',
                        style: TextStyle(
                          fontSize: 15,
                          color: Colors.white.withOpacity(0.9),
                          fontWeight: FontWeight.normal,
                        ),
                      ),
                    ],
                  )
                ],
              ),
              const SizedBox(
                height: 45,
              ),
              Text(
                'Total Balance',
                style: TextStyle(
                  fontSize: 25,
                  color: Colors.white.withOpacity(0.8),
                ),
              ),
              const Text(
                '\$5 194 382',
                style: TextStyle(
                    fontSize: 45,
                    color: Colors.white,
                    fontWeight: FontWeight.w800),
              ),
              const SizedBox(
                height: 20,
              ),
              const Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  Button(
                    text: 'Transfer',
                    bgColor: Color(0xFFF2B33A),
                    color: Colors.black,
                  ),
                  Button(
                    text: 'Request',
                    bgColor: _blackColor,
                    color: Colors.white,
                  ),
                ],
              ),
              const SizedBox(
                height: 70,
              ),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  const Text(
                    'Wallets',
                    style: TextStyle(
                        fontSize: 35,
                        color: Colors.white,
                        fontWeight: FontWeight.w700),
                  ),
                  Transform.translate(
                    offset: const Offset(0, 3),
                    child: Text(
                      'View All',
                      style: TextStyle(
                        fontSize: 17,
                        color: Colors.white.withOpacity(0.7),
                      ),
                    ),
                  ),
                ],
              ),
              const SizedBox(
                height: 20,
              ),
              const CurrencyCard(
                name: 'Euro',
                amount: '6 428',
                code: 'EUR',
                icon: Icons.euro,
                isInverted: false,
                order: 1,
              ),
              const CurrencyCard(
                name: 'Dollar',
                amount: '55 622',
                code: 'USD',
                icon: Icons.monetization_on_outlined,
                isInverted: true,
                order: 2,
              ),
              const CurrencyCard(
                name: 'Rupee',
                amount: '28 981',
                code: 'INR',
                icon: Icons.currency_rupee,
                isInverted: false,
                order: 3,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

 

#button.dart 코드

import 'package:flutter/material.dart';

class Button extends StatelessWidget {
  final String text;
  final Color bgColor;
  final Color color;

  const Button({
    super.key,
    required this.text,
    required this.bgColor,
    required this.color,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: bgColor,
        borderRadius: const BorderRadius.all(Radius.circular(40)),
      ),
      padding: const EdgeInsets.symmetric(
        vertical: 18,
        horizontal: 50,
      ),
      child: Text(
        text,
        style: TextStyle(
          fontSize: 18,
          color: color,
        ),
      ),
    );
  }
}

 

#currency_card.dart 코드

import 'package:flutter/material.dart';

const _blackColor = Color(0xFF1F2123);

class CurrencyCard extends StatelessWidget {
  final String name, code, amount;
  final IconData icon;
  final bool isInverted;
  final int order;

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

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(0, order != 1 ? -30 * (order - 1) : 0),
      child: Container(
        clipBehavior: Clip.hardEdge,
        decoration: BoxDecoration(
            color: isInverted ? Colors.white : _blackColor,
            borderRadius: const BorderRadius.only(
              topLeft: Radius.circular(30),
              bottomRight: Radius.circular(30),
            )),
        child: Padding(
          padding: const EdgeInsets.symmetric(horizontal: 25),
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    name,
                    style: TextStyle(
                        color: isInverted ? _blackColor : Colors.white,
                        fontSize: 29,
                        fontWeight: FontWeight.w600),
                  ),
                  const SizedBox(
                    height: 15,
                  ),
                  Row(
                    crossAxisAlignment: CrossAxisAlignment.end,
                    children: [
                      Text(
                        amount,
                        style: TextStyle(
                            color: isInverted ? _blackColor : Colors.white,
                            fontSize: 22,
                            fontWeight: FontWeight.w400),
                      ),
                      const SizedBox(
                        width: 10,
                      ),
                      Text(
                        code,
                        style: TextStyle(
                          color: isInverted
                              ? _blackColor
                              : Colors.white.withOpacity(0.7),
                          fontSize: 18,
                        ),
                      ),
                    ],
                  )
                ],
              ),
              Transform.scale(
                scale: 1.2,
                child: Transform.translate(
                  offset: const Offset(15, 35),
                  child: Icon(
                    icon,
                    size: 150,
                    color: isInverted ? _blackColor : Colors.white,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}