import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[200],
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
Text(
'U & I',
style: TextStyle(
color: Colors.white,
fontFamily: 'parisienne',
fontSize: 80.0,
),
),
Text(
'우리 처음 만난날',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 30.0,
),
),
Text(
'2022.01.01',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 20.0,
),
),
IconButton(
iconSize: 60.0,
onPressed: () {},
icon: Icon(
Icons.favorite,
color: Colors.red,
)),
Text(
'D + 1',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 50.0,
fontWeight: FontWeight.w700),
),
],
),
),
),
);
}
}
Column 위젯을 잘라내서 _TopPart 위젯을 새로 만든다. _TopPart의 밑줄 의미는 이 파일에서 만 사용가능하다는 의미이다.
_TopPart 밑에 이미지 파일을 넣고 마찬가지로 _BottomPart를 만든다.
Expanded를 사용해서 크기를 조절했다.
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[200],
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
_TopPart(),
Expanded(
child: Image.asset(
'asset/img/heart.png',
),
),
],
),
),
),
);
}
}
class _TopPart extends StatelessWidget {
const _TopPart({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Expanded(
child: Column(
children: [
Text(
'U & I',
style: TextStyle(
color: Colors.white,
fontFamily: 'parisienne',
fontSize: 80.0,
),
),
Text(
'우리 처음 만난날',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 30.0,
),
),
Text(
'2022.01.01',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 20.0,
),
),
IconButton(
iconSize: 60.0,
onPressed: () {},
icon: Icon(
Icons.favorite,
color: Colors.red,
)),
Text(
'D + 1',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 50.0,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[200],
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
_TopPart(),
_BottomPart(),
],
),
),
),
);
}
}
class _TopPart extends StatelessWidget {
const _TopPart({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'U & I',
style: TextStyle(
color: Colors.white,
fontFamily: 'parisienne',
fontSize: 80.0,
),
),
Column(
children: [
Text(
'우리 처음 만난날',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 30.0,
),
),
Text(
'2022.01.01',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 20.0,
),
),
],
),
IconButton(
iconSize: 60.0,
onPressed: () {},
icon: Icon(
Icons.favorite,
color: Colors.red,
)),
Text(
'D + 1',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 50.0,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
class _BottomPart extends StatelessWidget {
const _BottomPart({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Expanded(
child: Image.asset(
'asset/img/heart.png',
),
);
}
}
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[200],
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
_TopPart(),
_BottomPart(),
],
),
),
),
);
}
}
class _TopPart extends StatelessWidget {
const _TopPart({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'U & I',
style: TextStyle(
color: Colors.white,
fontFamily: 'parisienne',
fontSize: 80.0,
),
),
Column(
children: [
Text(
'우리 처음 만난날',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 30.0,
),
),
Text(
'2022.01.01',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 20.0,
),
),
],
),
IconButton(
iconSize: 60.0,
onPressed: () {
// dialog
showCupertinoDialog(
context: context,
barrierDismissible: true,
// container 밖에 누르면 닫힌다.
builder: (BuildContext context) {
return Align(
// 정렬을 지정하지 않으면 container가 전체 영역을 차지한다.
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.white,
height: 300.0,
child: CupertinoDatePicker(
// 날짜를 선택하는 위젯
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime date) {
print(date);
},
),
),
);
},
);
},
icon: Icon(
Icons.favorite,
color: Colors.red,
)),
Text(
'D + 1',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 50.0,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
class _BottomPart extends StatelessWidget {
const _BottomPart({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Expanded(
child: Image.asset(
'asset/img/heart.png',
),
);
}
}
_TopPart
에 2022.01.01
과 D + 1
이 변경된 날짜에 기반에 데이터가 변경되어야 한다._TopPart
위젯을 Stateful
위젯으로 바꿔준다.class _TopPart extends StatefulWidget {
const _TopPart({Key? key}) : super(key: key);
State<_TopPart> createState() => _TopPartState();
}
class _TopPartState extends State<_TopPart> {
DateTime selectedDate = DateTime(
DateTime.now().year,
DateTime.now().month,
DateTime.now().day,
);
// 관리할 변수를 넣어준다
// 기본값을 현재 날짜로 설정한다.
// 변경된 날짜를 selectedDate에 업데이트 해준다.
// 선택된 날짜도 시분초가 필요없기 때문에 코드를 수정해준다.
Widget build(BuildContext context) {
final now = DateTime.now();
// 반복되는 코드를 간소화 한다.
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'U & I',
style: TextStyle(
color: Colors.white,
fontFamily: 'parisienne',
fontSize: 80.0,
),
),
Column(
children: [
Text(
'우리 처음 만난날',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 30.0,
),
),
Text(
'${selectedDate.year}.${selectedDate.month}.${selectedDate.day}',
// 변경된 날짜를 반영시킨다.
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 20.0,
),
),
],
),
IconButton(
iconSize: 60.0,
onPressed: () {
// dialog
showCupertinoDialog(
context: context,
barrierDismissible: true,
// container 밖에 누르면 닫힌다.
builder: (BuildContext context) {
return Align(
// 정렬을 지정하지 않으면 container가 전체 영역을 차지한다.
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.white,
height: 300.0,
child: CupertinoDatePicker(
// 날짜를 선택하는
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime date) {
setState(() {
selectedDate = date;
// onDateTimeChanged에서 바뀐 날짜를 selectedDate에 넣어준다.
});
// stateful 위젯에서 변수를 변경시킬 때, bulid가 변경될때 setState함수를 사용한다.
;
},
),
),
);
},
);
},
icon: Icon(
Icons.favorite,
color: Colors.red,
)),
Text(
'D + ${DateTime(
now.year,
now.month,
now.day,
).difference(selectedDate).inDays + 1}',
// 디데이에서 보통 `년, 월, 일`을 사용하기 때문에 코드를 수정해준다.
// 특정날짜까지의 기간을 구할 때는 difference를 사용한다.
// 만난 당일부터 1일 이기 때문에 + 1을 해준다.
// 반복되는 코드를 간소화 시킨다. DateTime.now()
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 50.0,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
IconButton(
iconSize: 60.0,
onPressed: () {
showCupertinoDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.white,
height: 300.0,
child: CupertinoDatePicker(
initialDateTime: selectedDate,
maximumDate: DateTime(
now.year,
now.month,
now.day,
),
// 미래의 날짜를 설정하게 되면 - 가 출력된다.
// 최대 날짜를 설정해 줘야한다.
// 하지마 미래 날짜를 설정하게 되면 에러가 출력된다.
// 이럴 때 initialDateTime을 사용하면 된다.
// CupertinoDatePicker가 처음 실행될 때의 날짜를 세팅한다.
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime date) {
setState(() {
selectedDate = date;
});
},
),
),
);
},
);
},
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
DateTime selectedDate = DateTime(
DateTime.now().year,
DateTime.now().month,
DateTime.now().day,
);
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.green[200],
body: SafeArea(
child: Container(
width: MediaQuery.of(context).size.width,
child: Column(
children: [
_TopPart(
selectedDate: selectedDate,
// 밑에 _TopPart에서 selectedDate가 필수이기 때문에 넣어준다.
onPressed: onHeartPressed,
// 여기에 onPressed 함수를 넣을 수 있지만 코드가 길어지기 때문에 _HomeScreenState 하단에 함수를 선언하고
// onPressed를 넣어준다.
),
_BottomPart(),
],
),
),
),
);
}
void onHeartPressed() {
final DateTime now = DateTime.now();
showCupertinoDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Align(
alignment: Alignment.bottomCenter,
child: Container(
color: Colors.white,
height: 300.0,
child: CupertinoDatePicker(
initialDateTime: selectedDate,
maximumDate: DateTime(
now.year,
now.month,
now.day,
// now 에러가 발생하게 되는데 함수 상단부에 선언해주면 된다.
),
mode: CupertinoDatePickerMode.date,
onDateTimeChanged: (DateTime date) {
setState(() {
selectedDate = date;
});
// setState는 stateless 위젯에서 사용할 수 없다.
// 상위 위젯으로 옮겨서 받아오는 방법이 있다.
// onPressed의 정의를 보면 VoidCallback 타입이다.
// VoidCallback은 아무것도 들어있지 않은 함수이다.
},
),
),
);
},
);
}
}
// _TopPart 위젯을 StatelessWidget으로 변경해야한다.
// selectedDate를 상단으로 옮긴다.
// 그러면 selectedDate와 setState 에러가 발생하게 된다.
// 이럴 때 constructor를 사용하면 된다.
class _TopPart extends StatelessWidget {
final DateTime selectedDate;
final VoidCallback onPressed;
_TopPart({
required this.selectedDate,
required this.onPressed,
Key? key,
}) : super(key: key);
Widget build(BuildContext context) {
final now = DateTime.now();
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'U & I',
style: TextStyle(
color: Colors.white,
fontFamily: 'parisienne',
fontSize: 80.0,
),
),
Column(
children: [
Text(
'우리 처음 만난날',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 30.0,
),
),
Text(
'${selectedDate.year}.${selectedDate.month}.${selectedDate.day}',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 20.0,
),
),
],
),
IconButton(
iconSize: 60.0,
onPressed: onPressed,
icon: Icon(
Icons.favorite,
color: Colors.red,
)),
Text(
'D + ${DateTime(
now.year,
now.month,
now.day,
).difference(selectedDate).inDays + 1}',
style: TextStyle(
color: Colors.white,
fontFamily: 'sunflower',
fontSize: 50.0,
fontWeight: FontWeight.w700),
),
],
),
);
}
}
class _BottomPart extends StatelessWidget {
const _BottomPart({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Expanded(
child: Image.asset(
'asset/img/heart.png',
),
);
}
}