Flutter/Flutter 기본

[Flutter] state를 상위트리에서 관리하기

Chafle 2023. 4. 20. 05:38
반응형
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

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

class _HomeScreenState extends State<HomeScreen> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.pink[100],
      body: SafeArea(
        bottom: false,
        child: Container(
          width: MediaQuery.of(context).size.width,
            child: Column(
              children: [
                    _TopPart(),
                    _BottomPart()
              ],
            )
        ),
      )
    );
  }
}

class _TopPart extends StatefulWidget {
  const _TopPart({Key? key}) : super(key: key);

  @override
  State<_TopPart> createState() => _TopPartState();
}

class _TopPartState extends State<_TopPart> {
  DateTime selectedDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day);
 
  @override
  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,
      ),),
      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 -> 화면 위에 화면을 덮는다.
        //cupertinoDialog는 아이폰이랑 비슷한 ui구현해준다
        //builder는 build함수와 같다 ->
        showCupertinoDialog(
            context: context,
            barrierDismissible: true,
            builder: (BuildContext context) {
              return Align(
                alignment: Alignment.bottomCenter,
                child: Container( // Flutter특징이 특정 위젯이 어디에 정렬하는지 알 수 없을 때는 전체화면을 먹어버림(Dialog는 전체화면)
                  color: Colors.white,
                  height: 300.0,
                  child: CupertinoDatePicker(
                    mode: CupertinoDatePickerMode.date,
                    initialDateTime: selectedDate, // 앱을 실행했을 때 초기값을 지정
                    maximumDate: DateTime( // 미래의 날짜를 제한을 둔다
                      now.year,
                      now.month,
                      now.day,
                    ),
                    onDateTimeChanged: (DateTime date){
                      setState(() {
                        selectedDate = date;
                      });
                    },
                  ),

                ),
              );
            }
        );
      },
      icon: Icon(
      Icons.favorite,
      color: Colors.red,
      )),
      Text('D+${
      DateTime(
        now.year,
        now.month,
        now.day,
      ).difference(selectedDate).inDays + 1 // 오늘날짜와 선택한 날짜와의 차이를 indays 날짜로 반환해라
      }',
      style: TextStyle(
      color: Colors.white,
      fontFamily: 'sunFlower',
      fontSize: 50.0,
      fontWeight: FontWeight.w700
      ),),
      ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Expanded(
        child: Image.asset('asset/img/middle_image.png')
    );
  }
}

 

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

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

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

class _HomeScreenState extends State<HomeScreen> {
// HomeScreen에서 관리할 데이터를 하위 위젯으로 뿌려주자.
  DateTime selectedDate = DateTime(DateTime.now().year, DateTime.now().month, DateTime.now().day);

  // selectedDate는 최상위 위젯에서 관리해야 데이터의 흐름을 쏴줄 수 있다


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.pink[100],
      body: SafeArea(
        bottom: false,
        child: Container(
          width: MediaQuery.of(context).size.width,
            child: Column(
              children: [ // 외부에서 받는다고 했는데 여기가 외부야
                    _TopPart(selectedDate: selectedDate,
                    onPressed: onHeartPressed,
                    ),
                    _BottomPart()
              ],
            )
        ),
      )
    );
  }
  void onHeartPressed(){
    DateTime now = DateTime.now();
      //dialog -> 화면 위에 화면을 덮는다.
      //cupertinoDialog는 아이폰이랑 비슷한 ui구현해준다
      //builder는 build함수와 같다 ->
      showCupertinoDialog(
          context: context,
          barrierDismissible: true,
          builder: (BuildContext context) {
            return Align(
              alignment: Alignment.bottomCenter,
              child: Container( // Flutter특징이 특정 위젯이 어디에 정렬하는지 알 수 없을 때는 전체화면을 먹어버림(Dialog는 전체화면)
                color: Colors.white,
                height: 300.0,
                child: CupertinoDatePicker(
                  mode: CupertinoDatePickerMode.date,
                  initialDateTime: selectedDate, // 앱을 실행했을 때 초기값을 지정
                  maximumDate: DateTime( // 미래의 날짜를 제한을 둔다
                    now.year,
                    now.month,
                    now.day,
                  ),
                  onDateTimeChanged: (DateTime date){
                    setState(() {
                      selectedDate = date;
                    });
                  },
                ),

              ),
            );
          }
      );
    }
  }


// class _TopPart extends StatefulWidget {
//   const _TopPart({Key? key}) : super(key: key);
//   @override
//   State<_TopPart> createState() => _TopPartState();
// }

class _TopPart extends StatelessWidget{

 // 1차적인 이해 - TopPart의 class에 매개변수를 넣어두고 상위 클래스에서 TopPart가 사용된다면, 매개변수에 상위 클래스에서 정의한

  final DateTime selectedDate;
  final VoidCallback onPressed;

  _TopPart({required this.selectedDate, required this.onPressed, Key? key}) : super(key:key);

  @override
  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,
      ),),
      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 // 오늘날짜와 선택한 날짜와의 차이를 indays 날짜로 반환해라
      }',
      style: TextStyle(
      color: Colors.white,
      fontFamily: 'sunFlower',
      fontSize: 50.0,
      fontWeight: FontWeight.w700
      ),),
      ],
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Expanded(
        child: Image.asset('asset/img/middle_image.png')
    );
  }
}
반응형