Project/MyNature

[TIL] 플러터 클래스로 변수값 받기, 다른 클래스로 변수 전달하기

컴퓨터 탐험가 찰리 2023. 7. 16. 21:08
728x90
반응형

 

문제상황

아래처럼 주별 날짜를 선택할 수 있는 스크롤바로 WeeklyDatePickerComponent 위젯을 만들고 이를 메인 스크린 클래스에 넣었다.

사용한 라이브러리: weekly_date_picker: ^1.3.0

Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Text(
      DateFormat('yyyy/MM/dd').format(_selectedDay ?? DateTime.now()),
      style: const TextStyle(
        fontSize: 16,
      ),
    ),
    WeeklyDatePickerComponent(
      onSelectedDayChanged: handleSelectedDayChanged,
    )
  ],
),

 

위쪽 2023/07/10 부분은 메인 스크린 클래스에서 사용하는 _selectedDay 변수를 바라보게 하였고, 아래쪽 날짜 선택 스크롤은 WeeklyDatePickerComponent를 사용하며, 여기서 날짜를 선택할 수 있게 GestureDetector의 onTap 속성이 적용되어있다.

 

class WeeklyDatePickerComponent extends StatefulWidget {

  final void Function(DateTime) onSelectedDayChanged;
  const WeeklyDatePickerComponent({super.key, required this.onSelectedDayChanged});

  @override
  State<WeeklyDatePickerComponent> createState() => _WeeklyDatePickerComponentState();
}

class _WeeklyDatePickerComponentState extends State<WeeklyDatePickerComponent> {

  DateTime selectedDay = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return WeeklyDatePicker(
      selectedDay: selectedDay,
      changeDay: (value) => setState(() {
        selectedDay = value;
        widget.onSelectedDayChanged(value);
      }),
      enableWeeknumberText: false,
      backgroundColor: Colors.white12,
      weekdayTextColor: Colors.black38,
      digitsColor: Colors.black38,
      selectedBackgroundColor: Color(0xFFBF95EA),
    );
  }
}

 

문제는 WeeklyDatePickerComponent에서 어떻게 메인스크린으로 사용자가 클릭한 정보를 넘겨줄 수 있느냐는 것이었다.

 

 

해결방법

 

일반적으로 어떤 클래스의 인스턴스에 데이터를 전달하기 위해서는 그 클래스의 생성자에 해당 변수를 정의하면 된다. 이건 아주 일반적이고 기초적인 방법이다.

 

class A {
  String name;

  const A{(required this.name)};

}


A(name="넘겨줄 이름");

 

그럼 위 상황처럼 클래스에 정의된 변수를 넘겨줄땐 어떻게 해야할까?

 

콜백 함수를 넘긴다.

이미 위에 작성한 것처럼 콜백함수를 넘기고 그것을 호출하도록 하면 된다.

WeeklyDatePickerComponent -> 메인스크린의 상황일때, 아래처럼 하면 된다.

 

 

1.  WeeklyDatePickerComponent가 Function 형태로 onSelectedDayChanged를 받을 수 있도록 변수를 선언하고 생성자에 넣는다. 그리고 라이브러리 스펙상 사용자의 탭이 발생했을 때 실행되는 changeDay에서 setState를 이용해서 widget.onSelectedDayChanged(value)를 통해 value값을 메인스크린으로 전달한다. State 클래스 바깥쪽에서 함수를 정의했으므로 widget.{함수명}으로 호출하였다.

class WeeklyDatePickerComponent extends StatefulWidget {

  final void Function(DateTime) onSelectedDayChanged;
  const WeeklyDatePickerComponent({super.key, required this.onSelectedDayChanged});

  @override
  State<WeeklyDatePickerComponent> createState() => _WeeklyDatePickerComponentState();
}

class _WeeklyDatePickerComponentState extends State<WeeklyDatePickerComponent> {

  DateTime selectedDay = DateTime.now();

  @override
  Widget build(BuildContext context) {
    return WeeklyDatePicker(
      selectedDay: selectedDay,
      changeDay: (value) => setState(() {
        selectedDay = value;
        widget.onSelectedDayChanged(value);
      }),
      ...
    );
  }
}

 

2. 메인스크린에서 이 위젯을 받는다. onSelectedDayChanged 함수를 생성자로 전달한다.

...중략
WeeklyDatePickerComponent(
                    onSelectedDayChanged: handleSelectedDayChanged,
                  )

 

3. 메인 스크린에서 전달받을 변수와 함수를 선언한다.

handleSelectedDayChanged 함수에서 value값을 받아왔고, 그 값을 setState를 통해서 _selectedDay 변수에 할당되도록 정의해주는 것이다.

class _MyHomePageState extends State<MyHomePage> {
  DateTime? _selectedDay;
  Map<String, dynamic>? randomQuestion;

  void handleSelectedDayChanged(DateTime value) {
    setState(() {
      _selectedDay = value;
    });
  }

 

728x90
반응형