calendar_widget.dart와 card_widgets로 크게 분할하였다.
card_widgets 내부에 총 5개의 하위 widget을 구성하였다.
main.dart
import 'package:flutter/material.dart';
import 'package:ui_clone/widgets/calendar_widget.dart';
import 'package:ui_clone/widgets/card_widgets/card_container_column_widget.dart';
void main() {
runApp(const PlannerApp());
}
class PlannerApp extends StatelessWidget {
const PlannerApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'PlannerApp',
debugShowCheckedModeBanner: false,
theme: ThemeData(
scaffoldBackgroundColor: Colors.black,
),
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.black,
leading: IconButton(
icon: const CircleAvatar(
radius: 40.0,
backgroundImage: AssetImage('assets/images/nico.jpg'),
),
onPressed: () {},
),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(
Icons.add,
color: Colors.white,
size: 30,
),
),
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20.0),
child: Column(
children: [
// for문으로 16일부터 31일까지 날짜를 매개변수로 보냄
CalendarWidget('MONDAY 16',
dates: [for (int i = 16; i <= 31; i++) i]),
// 3개의 CardContainer가 있는 별도의 ColumnWidget을 생성
const CardContainerColumnWidget(),
],
),
),
),
),
);
}
}
import 'package:flutter/material.dart';
class CalendarWidget extends StatelessWidget {
final String today;
final List<int> dates;
const CalendarWidget(
this.today, {
super.key,
required this.dates,
});
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 15.0,
),
Text(
today,
style: const TextStyle(
color: Colors.white70,
fontSize: 15.0,
fontWeight: FontWeight.w500,
),
),
const SizedBox(
height: 5.0,
),
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
children: [
const Text(
'TODAY',
style: TextStyle(
color: Colors.white,
fontSize: 40.0,
fontWeight: FontWeight.w400,
),
),
const SizedBox(width: 10),
Container(
width: 12.0,
height: 12.0,
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
),
Row(
children: [
...dates.map(
(date) => Padding(
padding: const EdgeInsets.symmetric(
horizontal: 15.0), // 좌우 간격 조정
child: Text(
'$date', // 날짜를 문자열로 변환
style: const TextStyle(
color: Colors.white54,
fontSize: 40.0,
fontWeight: FontWeight.w400,
),
),
),
),
],
),
],
),
),
],
);
}
}
import 'package:flutter/material.dart';
import 'package:ui_clone/widgets/card_widgets/card_container_widget.dart';
class CardContainerColumnWidget extends StatelessWidget {
const CardContainerColumnWidget({super.key});
Widget build(BuildContext context) {
return const Padding(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Column(
children: [
CardContainerWidget(
bgColor: Colors.yellowAccent,
time: [
'11',
'30',
'12',
'20',
],
schedule: 'DESIGN\nMEETING',
members: [
'ALEX',
'HELENA',
'NANA',
],
),
SizedBox(height: 20.0),
CardContainerWidget(
bgColor: Colors.pinkAccent,
time: [
'13',
'00',
'14',
'00',
],
schedule: 'LUNCH\nBREAK',
members: [
'NICO',
'LYNN',
'JOE',
],
),
SizedBox(height: 20.0),
CardContainerWidget(
bgColor: Colors.tealAccent,
time: [
'14',
'00',
'15',
'00',
],
schedule: 'NOMAD\nCHALLENGE',
members: [
'JOE',
'DEVIL',
'NICO',
],
),
],
),
);
}
}
import 'package:flutter/material.dart';
import 'package:ui_clone/widgets/card_widgets/card_members_widget.dart';
import 'package:ui_clone/widgets/card_widgets/card_schedule_widget.dart';
import 'package:ui_clone/widgets/card_widgets/card_time_widget.dart';
class CardContainerWidget extends StatelessWidget {
final Color bgColor;
final List<String> time;
final String schedule;
final List<String> members;
const CardContainerWidget({
super.key,
required this.bgColor,
required this.time,
required this.schedule,
required this.members,
});
Widget build(BuildContext context) {
return Container(
clipBehavior: Clip.hardEdge,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height * 0.25,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
color: bgColor,
),
child: Column(
children: [
const SizedBox(
height: 20.0,
),
Row(
children: [
CardTimeWidget(
time: time,
),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
CardScheduleWidget(
schedule: schedule,
),
CardMembersWidget(
members: members,
),
],
),
],
),
],
),
);
}
}
import 'package:flutter/material.dart';
class CardTimeWidget extends StatelessWidget {
final List<String> time;
const CardTimeWidget({
super.key,
required this.time,
});
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0,
),
child: Column(
children: [
Text(
time[0],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25.0,
),
),
Text(
time[1],
style: const TextStyle(
fontSize: 15.0,
),
),
const Text(
'|',
style: TextStyle(
fontSize: 15,
),
),
Text(
time[2],
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 25.0,
),
),
Text(
time[3],
style: const TextStyle(
fontSize: 15.0,
),
),
],
),
);
}
}
import 'package:flutter/material.dart';
class CardScheduleWidget extends StatelessWidget {
final String schedule;
const CardScheduleWidget({
super.key,
required this.schedule,
});
Widget build(BuildContext context) {
return Column(
children: [
Text(
schedule,
style: const TextStyle(
fontWeight: FontWeight.w700,
fontSize: 50.0,
),
),
],
);
}
}
import 'package:flutter/material.dart';
class CardMembersWidget extends StatelessWidget {
final List<String> members;
const CardMembersWidget({super.key, required this.members});
Widget build(BuildContext context) {
return Row(
children: members
.map((member) => [
Text(
member,
style: const TextStyle(
color: Colors.black38,
),
),
const SizedBox(width: 20.0), // 각 멤버 사이의 간격
])
.expand((element) => element) // 리스트를 평탄화
.toList(),
);
}
}