이 강의를 통해서 flutter가 진짜 매우 편하다는 것을 알게 되었다.(그냥 다 알아서 해줘...)
이번에는 이 부분을 만들 것이다.
가장 먼저, Container 부분이 반복되니까 ./widgets/currency_card.dart 파일을 만들어서 위젯을 따로 뺄 것이다.
이전에 button.dart 파일에서 했던 것과 동일하게 진행하면 된다...
자세한 방법은 3.5 Reusable Widget(https://want-to-work-life-balance.tistory.com/entry/Flutter-35-Reusable-Widgets)에 있다.
currency name, currency code, currency amount, currency icon을 변수로 두었다.
하지만, 비트코인쪽을 보면 색이 반대가 되어 있다. 따라서, 변수를 하나 추가했다. 어떻게?
이렇게 true or false로 받도록(무조건 받도록 했다.) 설정한 후에, Euro는 false, Bitcoin은 true로 해서 색을 반전시키도록 한다.
물론, 이렇게 변수만 추가하면 아무것도 없다.
color: isInverted ? Colors.white : _blackColor,
이런 방식으로 true라면 white를, false라면 _blackColor가 되도록 설정한다.
참고로, _blackColor는 Color(0xFF1F2123)으로 두었다.
이제 이것을 Dollar에도 붙여 넣은 후에, Transform.translate를 이용해서 겹치도록 설정한다.
만약, scroll이 되게 하고 싶다면, 가장 큰 Padding에 SingleChildScrollView를 감싼다.
생각보다, AI가 짜준 flutter 코드를 읽기 위해서 노력했던 과거가 도움이 되었다. 대충 어떻게 진행될지 눈에 보이기는 한다.
이 즈음에 전체 코드를 올려볼까 싶다.
전체 코드
main.dart
import 'package:flutter/material.dart';
import 'package:toonflix/widgets/currency_card.dart';
import './widgets/button.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: [
// SizedBox: 빈 박스
const SizedBox(
height: 40,
),
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.8),
fontSize: 18,
),
),
],
),
],
),
const SizedBox(
height: 20,
),
Text(
'Total balance',
style: TextStyle(
fontSize: 22,
color: Colors.white.withOpacity(0.8),
),
),
const SizedBox(
height: 5,
),
const Text(
// dart에서 $는 변수를 가져올때 사용하므로 \를 붙여줘야 한다.
'\$5 194 482',
style: TextStyle(
fontSize: 48,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
const SizedBox(
height: 30,
),
const Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Button(
text: 'Transfer',
bgcolor: Color(0xFFF2B33A),
textColor: Colors.black,
),
Button(
text: 'Request',
bgcolor: Color(0xFF1F2123),
textColor: Colors.white,
),
],
),
const SizedBox(
height: 60,
),
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.8),
fontSize: 18,
),
),
],
),
const SizedBox(
height: 20,
),
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, -40),
child: const CurrencyCard(
name: 'Dollar',
code: 'USD',
amount: '428',
icon: Icons.attach_money_outlined,
isInverted: false,
),
),
],
),
),
),
),
);
}
}
./widgets/button.dart
import 'package:flutter/material.dart';
class Button extends StatelessWidget {
final String text;
final Color bgcolor;
final Color textColor;
const Button({
// key는 나중에 설명할 것이다.
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(
vertical: 20,
horizontal: 40,
),
child: Text(
text,
style: TextStyle(
fontSize: 20,
color: textColor,
),
),
),
);
}
}
./widgets/currency_card.dart
import 'package:flutter/material.dart';
class CurrencyCard extends StatelessWidget {
final String name, code, amount;
final IconData icon;
final bool isInverted;
const CurrencyCard({
super.key,
required this.name,
required this.code,
required this.amount,
required this.icon,
required this.isInverted,
});
final _blackColor = const Color(0xFF1F2123);
// customizable: currency name, currency code, currency amount, currency icon
// 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: 20,
),
),
const SizedBox(
height: 10,
),
Row(
children: [
Text(
amount,
style: TextStyle(
color: isInverted ? _blackColor : Colors.white,
fontSize: 20,
),
),
const 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: const Offset(-5, 12),
child: Icon(
icon,
color: isInverted ? _blackColor : Colors.white,
size: 88,
),
),
),
],
),
),
);
}
}