[플러터] 10. 만난 지 며칠 U&I

Jun·2024년 3월 6일
0

사전 지식

setState() 함수

State를 상속하는 모든 클래스는 setState() 함수를 사용할 수 있습니다. setState() 함수가 실행되는 과정은 다음과 같이 5단계입니다.
1. 클린 상태
2. setState()
3. 더티 상태
4. build()
5. 클린 상태

setState() 함수는 매개변수로 콜백함수를 입력받습니다.
단, 비동기 함수는 안됩니다.

showCupertinoDialog() 함수

ios 스타일로 다이얼로그가 실행되는 함수입니다.

import 'package:flutter/cupertino.dart

showCupertinoDialog(
  context: context, // BuildContext 입력
  barrierDismissible: true, // 외부 탭해서 닫을 수 있음
  builder: (BuildContext context) { // 다이얼로그에 들어갈 위젯
    return Text('Dialog');
  },
);

코드

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 firstDay = DateTime.now();

  void onHeartPressed() {
    showCupertinoDialog( // 다이얼로그 실행
      context: context,
      builder: (BuildContext context) {
        return Align( // child를 정렬함
          alignment: Alignment.bottomCenter,
          child: Container(
            height: 300,
            child: CupertinoDatePicker( // 날짜 선택 위젯
              mode: CupertinoDatePickerMode.date,
              onDateTimeChanged: (DateTime date) {
                setState(() { // 날짜 변경 시 firstDay를 변경하로 리빌드
                  firstDay = date;
                });
              },
            ),
          ),
        );
      },
      barrierDismissible: true, // 외부 탭으로 위젯 닫음
    );
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.pink[100],
      body: SafeArea(
        top: true,
        bottom: false,
        child: Column( // children을 세로로 정렬
          mainAxisAlignment: MainAxisAlignment.spaceBetween, // 위, 아래 양 끝으로 정렬
          crossAxisAlignment: CrossAxisAlignment.stretch, // 가로의 너비를 최대로
          children: [
            _DDay( // 날짜를 표시하는 위젯으로 상태 값과 이벤트 핸들러를 주입
              onHeartPressed: onHeartPressed,
              firstDay: firstDay,
            ),
            _CoupleImage(),
          ],
        ),
      ),
    );
  }
}

class _DDay extends StatelessWidget {
  final GestureTapCallback onHeartPressed;
  final DateTime firstDay;

  _DDay({
    required this.onHeartPressed,
    required this.firstDay,
  });

  
  Widget build(BuildContext context) {
    final now = DateTime.now();

    return Column(
      children: [
        const SizedBox(height: 16.0),
        Text(
          'U&I',
        ),
        const SizedBox(height: 16.0),
        Text(
          '우리 처음 만난 날',
        ),
        const SizedBox(height: 16.0),
        Text(
          '2023.08.08',
        ),
        const SizedBox(height: 16.0),
        IconButton(
          iconSize: 60.0,
          onPressed: this.onHeartPressed,
          icon: Icon(
            Icons.favorite,
          ),
        ),
        const SizedBox(height: 16.0),
        Text(
            'D+${DateTime(now.year, now.month, now.day).difference(firstDay).inDays + 1}')
      ],
    );
  }
}

class _CoupleImage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Expanded(
      child: Center(
        child: Image.asset(
          'asset/img/middle_image.png',
          height: MediaQuery.of(context).size.height / 2,
        ),
      ),
    );
  }
}

《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.

profile
HiHi

0개의 댓글