본문 바로가기
버킷리스트/앱 만들기

오공완(with 코드팩토리의 플러터 프로그래밍) #9 (만난 지 며칠 U&I)

by 또또도전 2024. 7. 29.
반응형

// 이곳에 쓴 내용은 앱 만들기라는 버킷리스트를 달성하기 위해 플러터를 공부하면서 정리하고 있는 내용입니다.

플러터에 대해 아는 것이 거의 없기 때문에 정리하면서 오류가 있을 수 있습니다.

오류를 발견하신 분은 댓글 남겨 주시면 감사하겠습니다.

 

오랫동안 공부를 안 한 만큼 오늘 최선을 다해서 열심히 공부해 보자.

 

오늘 배울 때 필요한 지식은 setState(), showCupertinoDialog(), 이미지와 폰트추가, pubspec.yaml, 프로젝트 초기화, 홈 스크린 UI, 상태 관리 연습, 날짜 선택 구현, 변경 값 상태 관리에 적용이란다.

 

  setState 함수, showCupertinoDialog 함수

 

-setState함수

StatefulWidget이 렌더링? 되면 클린 상태가 된단다. 그리고 setState를 실행하면 더티 상태가 되고, build함수를 거쳐 다시 클린 상태로 된다고..

 

-CupertinoDialog함수

iOS 스타일의 다이얼로그가 실행, 날짜 선택할 때 안드로이드보다 iOS 스타일이 더 이쁘니깐 잘 활용해 봐야겠다.

 

  이미지, 폰트 추가

 

1. 프로젝트 폴더에 asset폴더  추가, 그 밑에 img폴더와 font폴더 추가 그리고 각 폴더에 이미지와 폰트 추가

2. pubspec.yaml에 이미지와 폰트 등록(pub get 하는 거 잊지 않기)

왼쪽은 오류, 오른쪽은 정상 어디가 잘못됐냐~!! 바로 assets--;;

오타 하나를 찾는데 시간이..ㅜ.ㅜ

 

3. 홈스크린 다트 파일 생성 및 메인 다트 파일 수정

 

4. 홈스크린을 2개로 나누고, 배경을 분홍색으로 지정, coupleimage 위젯의 이미지의 크기를 전체 크기의 반으로 지정

 

5. dday위젯 가안으로 위치 및 글 추가

 

6. dday 위젯 폰트 스타일 지정(StatelessWidget을 만들어도 되고, 테마를 사용해도 된다고 함. 이번에는 테마를 사용)

이상하다. 파리지엥 폰트가 적용이 안되어 있어서 자세히 보니 오타.. 잘 작성 후에 실행했는데 , 이번에는 아래 부분에 이상한 녀석들이 생겼다.

 

다음페이지를 읽어보니 설명이 나와 있다. 오버플로우 현상이란다. 화면을 넘쳤다는 의미..

expanded를 사용해서 해결하고..

 

7. statefulWidget 추가(setState() 함수)

이 단계에서 오류가 시작, 일단 다음 단계로 넘어가서 최종 깃허브 코드랑 어디가 다른지 찾아봐야겠다.

 

8. CupertinoDatePicker로 날짜 선택 구현하기

역시나 오류~ 내가 작성한 것과 코드팩토리가 작성한 것을 비교해도 어디가 다른 지 못 찾겠다..ㅜ.ㅜ

여러 개의 오류가 있었는데, 마지막까지도 못 찾은 것은 createState인데 creatState로 쓴 오류..

오류 코드가 HomeScreen위젯이 잘못되었다는 내용 같아서 다행히도 단축키? (stful)로 작성해 보고, 어디가 다른지 일일이 비교해 보았다.

CupertinoDatePicker도 잘 작동한다.

추가 설명>

. of(context) 가장 가까이에 있는 객체의 값을 가져온다고 한다. 위로 올라가면서..

예) Theme.of(context), Navigator.of(context)

 

fontFamily: 기본 글씨체를 지정

textTheme: Text 위젯 테마를 지정

tabBarTheme, cardTheme, appBarTheme, floatingActionButtonTheme, elevatedButtonTheme, checkboxTheme, 등

 

CupertinoDatePickerMode.date: 날짜

CupertinoDatePickerMode.time: 시간

CupertinoDatePickerMode.dateAdnTime: 날짜와 시간

 

import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  DateTime firstDay = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.pink[100],
      body: SafeArea(
        top: true,
        bottom: false,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            _DDay(
              onHeartPressed: onHeartPressed,
              firstDay: firstDay,
            ),
            _CoupleImage(),
          ],
        ),
      ),
    );
  }

  void onHeartPressed() {
    showCupertinoDialog(
      context: context,
      builder: (BuildContext context) {
        return Align(
          alignment: Alignment.bottomCenter,
          child: Container(
            color: Colors.white,
            height: 300,
            child: CupertinoDatePicker(
              mode: CupertinoDatePickerMode.date,
              onDateTimeChanged: (DateTime date) {
                setState(() {
                  firstDay = date;
                });
              },
            ),
          ),
        );
      },
      barrierDismissible: true,
    );
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    final textTheme = Theme.of(context).textTheme;
    final now = DateTime.now();

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

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