Flutter
[Flutter] UI 그리기 연습(5) - 반복되는 카드를 하나의 위젯으로
건물주개발자
2023. 8. 7. 00:07
- UI 그리기 연습 시리즈는 아래 링크의 홈화면을 그려보는 포스팅입니다.
https://dribbble.com/shots/19858341-Finnancial-Mobile-IOS-App
Financial Mobile IOS App
dribbble.com
- 코드 설명 (코드 작성 순서로)
- 카드를 새로운 클래스(CurrencyCard)로 만들어 widgets 아래로 새로운 파일로 만든다.
- 화폐이름(name), 총액(amount), 코드(code), 아이콘(icon), 반전유무(isInverted)를 final 형태로 지정한다. 변할 수 있는 값들이기 때문에 클래스 생성자를 호출하면서 값들을 각자 호출한다. 반전유무를 통해 검은색/흰색 으로 배경색이나 글자색을 지정하기 위해 final로 _blackColor를 지정한다.
- main.dart에는 원래 Container자리에 CurrencyCard 클래스를 넣는다. 클래스를 넣으면서 name, code, icon, amount, isInverted 속성에 구체적인 값을 넣어준다. 다만 두번째, 세번째 카드는 첫번째, 두번째 카드에 겹쳐보이는 효과가 필요하기 때문에 Transform.translate 클래스의 offset 속성에 Offset(0, -20)으로 겹치는 효과를 주고, child속성에 CurrencyCard를 넣어준다.
- 끝!
이렇게 5회로 홈화면 프로젝트는 끝이 납니다.
좋은 비판이나 댓글 환영합니다.
// lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter_application_1/widgets/Button.dart';
import 'package:flutter_application_1/widgets/currency_card.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: const Color(0xFF181818),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(height: 80),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Text(
"Hey, Selena",
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.w800,
),
),
Text(
"Welcome back",
style: TextStyle(
color: Colors.white.withOpacity(0.4),
fontSize: 18,
),
),
],
),
],
),
const SizedBox(
height: 70,
),
const Text(
"Total Balance",
style: TextStyle(
fontSize: 22,
color: Colors.white,
),
),
const SizedBox(
height: 5,
),
const Text(
"\$ 5 194 382",
style: TextStyle(
fontSize: 48,
color: Colors.white,
),
),
const SizedBox(
height: 30,
),
const Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Button(
text: "Transfer",
bgColor: Color(0xFFF1B33B),
textColor: Colors.black,
),
Button(
text: "Request",
bgColor: Color(0xFF1F2123),
textColor: Colors.white,
),
],
),
const SizedBox(
height: 30,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
const Text(
"Wallets",
style: TextStyle(
color: Colors.white,
fontSize: 36,
fontWeight: FontWeight.w600,
),
),
Text(
"View All",
style: TextStyle(
color: Colors.white.withOpacity(0.6),
fontSize: 18,
),
),
],
),
const SizedBox(
height: 30,
),
const CurrencyCard(
name: "Euro",
code: "Eur",
amount: "6 428",
icon: Icons.euro_rounded,
isInverted: false,
),
Transform.translate(
offset: const Offset(0, -20),
child: const CurrencyCard(
name: "Bitcoin",
code: "BTC",
amount: "9 785",
icon: Icons.currency_bitcoin,
isInverted: true,
),
),
Transform.translate(
offset: const Offset(0, -20),
child: const CurrencyCard(
name: "Dollar",
code: "USD",
amount: "428",
icon: Icons.attach_money_outlined,
isInverted: false,
),
),
],
),
),
),
),
);
}
}
// lib/widgets/currency_card.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(20),
),
child: Padding(
padding: const EdgeInsets.all(25),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
name,
style: TextStyle(
fontSize: 32,
color: isInverted ? _blackColor : Colors.white,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
height: 10,
),
Row(
children: [
Text(
amount,
style: TextStyle(
fontSize: 20,
color: isInverted ? _blackColor : Colors.white,
fontWeight: FontWeight.w600,
),
),
const SizedBox(
width: 5,
),
Text(
code,
style: TextStyle(
fontSize: 20,
color: isInverted
? _blackColor
: Colors.white.withOpacity(0.8),
),
),
],
)
],
),
Transform.scale(
scale: 2.2,
child: Transform.translate(
offset: const Offset(-5, 12),
child: Icon(
icon,
size: 88,
color: isInverted ? _blackColor : Colors.white,
),
),
),
],
),
),
);
}
}
// lib/widgets/Button.dart
import 'package:flutter/material.dart';
class Button extends StatelessWidget {
final String text;
final Color bgColor;
final Color textColor;
const Button({
super.key,
required this.text,
required this.bgColor,
required this.textColor,
});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: bgColor,
borderRadius: BorderRadius.circular(45),
),
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 15),
child: Text(
text,
style: TextStyle(
fontSize: 20,
color: textColor,
),
),
),
);
}
}