관리 메뉴

피터의 개발이야기

[flutter] 만난 지 며칠 U&I, Cupertino DatePicker 설정 본문

Programming/Flutter

[flutter] 만난 지 며칠 U&I, Cupertino DatePicker 설정

기록하는 백앤드개발자 2024. 2. 20. 09:04
반응형

 

ㅁ 들어가며

코드팩토리의 플러터 프로그래밍 책을 보며 실습한 내용이다.

ㅇ 9장 만난 지 며칠 U&I를 만드는 과정이다.

핵심 목표

  - StatefulWidget의 setState 함수 이용방법

  - Cupertino 위젯을 이용한 다이얼로그 및 데이터픽커

 

ㅁ 프로젝트 생성 및 이미지와 폰트 추가

ㅇ 프로젝트 이름: u_and_i

 ㅇ 이미지와 font도 복사를 하였다.

 

  assets:
    - asset/img/

  fonts:
    - family: parisienne  # 폰트 이름 지정
      fonts:
        - asset: asset/font/Parisienne-Regular.ttf  # 폰트 PATH

    - family: sunflower
      fonts:
        - asset: asset/font/Sunflower-Light.ttf
        - asset: asset/font/Sunflower-Medium.ttf
          weight: 500  # 폰트 두께
        - asset: asset/font/Sunflower-Bold.ttf
          weight: 700

ㅇ pubspec.yaml 설정 후 pub get 실행하여 변경사항 반영.

 

 

ㅁ 프로젝트 초기화

// main.dart
import 'package:flutter/material.dart';
import 'package:u_and_i/screen/home_screen.dart';

void main() {
  runApp(
    MaterialApp(
      home: HomeScreen(),
    )
  );
}

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

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  // 프로젝트 초기세팅
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // https://api.flutter.dev/flutter/widgets/Text-class.html
      // 응용한 Text 출력
      body: const Center(
        child: SelectionArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('This is the way!!'),
            ],
          ),
        ),
      ),
    );
  }
}

ㅇ Flutter > widgets.dart > Text class  문서를 참고하여 가운데 기본 글자를 생성해 보았다.

 

 

ㅁ 홈 스크린 UI 구현하기

ㅇ 커플이미지구성

import 'package:flutter/material.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  // 홈 스크린 UI 구현하기
  @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(),
            _CoupleImage(),
          ],
        ),
      ),

      // https://api.flutter.dev/flutter/widgets/Text-class.html
      // 응용한 Text 출력
      /*body: const Center(
        child: SelectionArea(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text('This is the way!!'),
            ],
          ),
        ),
      ),*/
    );
  }
}

// _DDay 위젯
class _DDay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('DDay Widget'),
    );
  }
}

// 커플이미지 구성
class _CoupleImage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Image.asset(
        'asset/img/middle_image.png',

        // 화면 반만큼 높이 설정
        height: MediaQuery.of(context).size.height / 2,
      ),
    );
  }
}

 

ㅇ _DDay 위젯 - 텍스트 구성

// _DDay 위젯
class _DDay extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        const SizedBox(height: 80),
        Text('U&I'),
        const SizedBox(height: 16),
        Text('우리 처음 만난 날'),
        Text('2024.02.20'),
        const SizedBox(height: 16),
        IconButton(
          iconSize: 60,
          onPressed: (){},
          icon: Icon(
            Icons.favorite,
          ),
        ),
        const SizedBox(height: 16),
        Text('D+365'),
      ],
    );
  }
}

 

 

ㅇ _DDay 위젯 - 테마 지정 및 오버플로워 해결

 ㅇ 테마 지정을 하면서 화면구성 오버플로워가 발생하였다.

 ㅇ 커플 이미지에 Expanded를 사용하여 해결함.

 

ㅁ 상태 관리 - Stateful

 ㅇ stateless -> stateful로 변경

 

ㅇ 하트 기능 생성 및 위젯에 주입하여 버튼에 연결하기

 

 ㅇ 하트를 클릭 시 로그 확인

D/EGL_emulation( 9867): app_time_stats: avg=167888.84ms min=167888.84ms max=167888.84ms count=1
I/flutter ( 9867): Heart beating!!

 

ㅇ 위젯에 날짜 계산로직 적용

 

ㅇ 하트 클릭 시 하루 씩 시작일을 빼기

 ㄴ 하트 클릭 시 시작일이 하루씩 감소하면서 D+가 증가함.

 

ㅁ Cupertino DatePicker로 날짜선택

ㅇ Cupertino DatePicker initialize

 

 

9장 만난 지 며칠 U&I - Cupertino DatePicker 위치 조정 및 배경 조정

 

 

 9장 만난 지 며칠 U&I - Cupertino DatePicker 선택한 날짜 firstDay에 반영하기

  // 하트 기능 생성
  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,
              // 선택한 날짜 데이터 받아 firstDay에 반경하기
              onDateTimeChanged: (DateTime date){
                setState(() {
                  firstDay = date;
                });
              },
            ),
          ),
        );
      },
      barrierDismissible: true, // 외부 클릭 시 닫음
    );
  }

 ㅇ 하트 클릭 시 다어어그램 표출 후 DDay 기능까지 구현을 위한 코드

 

9장 만난 지 며칠 U&I - 다이어그램 한국어 지원

 

ㅇ pubspec.yaml 수정

  flutter:
    sdk: flutter

  flutter_localizations:
    sdk: flutter

 

ㅇ main.dart 한글 지정

import 'package:flutter_localizations/flutter_localizations.dart';

void main() {
  runApp(
    MaterialApp(
      // 한글 다이어그램 지정
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,   // for 안드로이드
        GlobalCupertinoLocalizations.delegate,  // for IOS
        GlobalWidgetsLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('ko', 'KO'),
      ],

 

ㅇ home_screen.dart에 다국어 페키지 import

import 'package:flutter_localizations/flutter_localizations.dart';

 

 9장 만난 지 며칠 U&I - 미래 날짜 선택 방지 

 

import 'package:intl/intl.dart'; // Dateformat 용
.............

  // 하트 기능 생성
  void onHeartPressed(){
    // 쿠퍼티노 다이어로그 생성자
    showCupertinoDialog(

      context: context,
      builder: (BuildContext context){
        // 미래 날짜 선택 방지- 설정 날짜
        final initDate =
          DateFormat('yyyy-MM-dd').parse('2014-11-11');

        // 날짜 다이얼로그 정렬
        return Align(
          alignment: Alignment.bottomCenter,
          child: Container(
            color: Colors.white, // 흰색 배경
            height: 300,
            child: CupertinoDatePicker(
              // 미래 날짜 선택 방지
              // https://api.flutter.dev/flutter/cupertino/CupertinoDatePicker/maximumDate.html
              maximumYear: DateTime.now().year,
              maximumDate: DateTime.now(),
              minimumYear: 2000,
              initialDateTime: initDate,
              
              // 시간 빼고 날짜만 선택
              mode: CupertinoDatePickerMode.date,
              // 선택한 날짜 데이터 받아 firstDay에 반경하기
              onDateTimeChanged: (DateTime date){
                setState(() {
                  firstDay = date;
                });
              },
            ),
          ),
        );
      },
      barrierDismissible: true, // 외부 클릭 시 닫음
    );
  }
.............

 

ㅁ 함께 보면 좋은 사이트

flutter cookbook - CupertinoDatePicker class

  ㄴ 플루터 쿡북 중 Cupertino DatePicker 링크

ㅇ codelabs- 첫 번째 Flutter 앱

  ㄴ 환경을 잡고 테스트를 해보기 좋은 튜토리얼

반응형
Comments