[플러터] 9. 전자액자: 위젯 생명주기

Jun·2024년 2월 28일
0

위젯 생명주기

StatelessWidget

상태가 없는 위젯입니다.
생명주기는 먼저 해당 위젯이 빌드되면 생성자가 실행됩니다.
이어서 필수로 오버라이드 해야 하는 build() 함수가 실행됩니다.
마지막으로 build() 함수에 반환한 위젯이 화면에 렌더링됩니다.
StatelessWidget의 build() 함수는 재실행되지 않습니다.

StatefulWidget

build()가 실행되기까지 과정은 StatelessWidget과 같습니다.
반면에 StatefulWidget은 build()를 재실행할 수 있습니다.

기본 생명주기

상태변경이 없는 생명주기는 나타나고 사라지기까지 중간에 위젯의 상태가 변경되지 않습니다
1. StatefulWidget 생성자가 실행됩니다.
2. createState() 함수가 실행되며, StatefulWidget과 연동되는 State를 생성합니다.
3. State가 생성되면 initState()가 실행됩니다. (최초 1번)
4. didChangeDependencies()가 실행됩니다. (State가 의존하는 값이 변경되면 반복)
5. State의 상태가 dirty로 설정됩니다.
6. dirty로 인해 build()가 재실행되고, 화면에 반영됩니다.
7. build가 완료되면 clean상태가 됩니다.
8. 위젯이 위젯트리에서 사라지면 deactivate()가 실행됩니다. (State가 일시적 또는 영구적으로 삭제될 때)
9. 위젯이 영구적으로 삭제될 때 dispose()가 실행됩니다.

생성자의 매개변수가 변경되었을 때 생명주기

  1. StatefulWidget 생성자가 실행됩니다.
  2. State의 didUpdateWidget() 함수가 실행됩니다.
  3. State가 dirty 상태로 변경됩니다.
  4. build()가 실행됩니다.
  5. State의 상태가 clean으로 변경됩니다.

State 자체적으로 build()를 재실행할 때 생명주기

  1. State 클래스의 setState()를 실행합니다.
  2. State가 dirty 상태로 변경됩니다.
  3. build()가 실행됩니다.
  4. State의 상태가 clean으로 변경됩니다.

전자액자 코드

main.dart

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

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

/screen/home_screen.dart

import 'package:flutter/material.dart';
import 'dart:async'; // 타이머를 사용하기 위해 import

// 타이머를 사용하기 위해 StatefulWidget 사용
class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  // 연동할 State를 생성
  
  State<HomeScreen> createState() => _HomeScreenState();
}

// 상태는 StatefulWidget을 매개변수로 받는 State 클래스를 상속 받음 (타입이 State<HomeScreen> 이 됨)
class _HomeScreenState extends State<HomeScreen> {
  final PageController pageController = PageController();

  // State가 생성되면 initState() 실행됨
  
  void initState() {
    super.initState();
    
    // initState()는 최초 1번만 실행되기 때문에 여기서 Timer를 생성함
    Timer.periodic(Duration(seconds: 3), (timer) {
      int? nextPage = pageController.page?.toInt();

      if (nextPage == null) {
        return;
      }

      if (nextPage == 4) {
        nextPage = 0;
      } else {
        nextPage += 1;
      }
      
      // 타이머에 설정한 시간 간격으로 페이지를 이동시킴
      pageController.animateToPage(
        nextPage,
        duration: Duration(milliseconds: 500),
        curve: Curves.ease,
      );
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: PageView(
        controller: pageController,
        // 5개의 이미지를 페이지로 나열
        children: [1, 2, 3, 4, 5]
            .map((number) => Image.asset(
                  'asset/img/image_$number.jpeg',
                  fit: BoxFit.cover,
                ))
            .toList(),
      ),
    );
  }
}

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

profile
HiHi

0개의 댓글