넘치게 채우기

2장. 위젯의 빌드, 그리고 생명주기 본문

개발/Flutter + Dart

2장. 위젯의 빌드, 그리고 생명주기

riveroverflow 2023. 6. 22. 21:41
728x90
반응형

material.dart 라이브러리를 불러와서 구글의 머리티얼 디자인 기반의 기본 위젯을 사용할 수 있습니다.

iOS스타일을 지원하는 cupertino.dart도 있습니다.

import 'package:flutter/material.dart';

 

앱의 진입점

void main() => runApp(MyApp());

플러터에서는 runApp이라는 메서드로 앱 위젯 트리의 최상위 위젯을 감싸서 실행시킵니다.

 

 

build 메서드

모든 위젯은 다른 위젯을 반환하는 build 메서드를 반드시 포함합니다.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

앱의 가장 상위 위젯인 MyApp 위젯입니다.

build 메서드를 호출하여 UI를 출력하도록 리턴시킵니다.

BuildContext 타입은 현재 위젯의 위젯트리상에서의 위치 정보를 담습니다.
context는 아래 리턴하는 위젯의 부모의 위치를 가지고 있는 것이죠.

 

 

위젯 트리의 코드 표현

	@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

위젯에서 자신의 자식이 또 다른 위젯을 포함한다고 설명하는 방식으로 코드를 표현합니다.

child나 children, builder 등으로 프로피터를 가집니다.

 

 

상태를 갖지 않는 위젯

StatelessWidget은 위젯의 생명주기 동안 내부 상태를 가지고 있지 않습니다.

설정이나 자신이 표시하는 데이터를 신경 쓸 필요가 없습니다.

 

상태를 갖는 위젯

상태를 갖는 위젯 StatefulWidget은 내부 상태를 가지며 이를 관리합니다.

상태를 갖는 모든 위젯은 상태 객체를 가집니다. 이 둘은 부모-자식 관계입니다.

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
	// 모든 StatefulWidget은 상태 객체를 반환하는 createState 메서드를 반드시 정의해야 합니다.
}

class _MyHomePageState extends State<MyHomePage> { // 상태 객체는 State를 상속받습니다.
  @override
  Widget build(BuildContext context) {
    //
  }
}

 

StatefulWidget에서는 build메서드를 상태 객체에서 포함합니다.

 

 

 

setState()

setState는 build, createState와 같이 중요한 메서드입니다.

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
//setState는 플러터에서 이 콜백함수가 실행된 뒤, 바뀌는 모든 위젯이 바뀌도록 플러터에게 요청합니다.
      _counter++;
    });

기본 카운터 앱에서 버튼이 눌러지고 숫자가 오르는 것을 지난 게시글에서 확인할 수 있었습니다.

이는 플러터가 위젯들을 새로 그릴 것을 요청받고 화면에 새롭게 출력시키는 것입니다.

 

initState()

initState 메서드는 플러터가 상태가 있는 위젯과 그 상태 객체를 만들 때, 가장 먼저 실행되는 메서드입니다.

위젯이 생성될 때 한번만 실행됩니다.

class PageState extends State<Page> {
	@override
	initState(){
	super.initState(); //부모 클래스(StatefulWidget)의 초기화부터 해줘야 합니다.
	//..
	}
}

Widget build(BuildContext context) {
	//..
}

 

 

didChangeDependencies()

생명 주기에서 initState()뒤에 처음으로 호출되며,

데이터의 의존성이 바뀌는 경우에도 호출되는 메서드입니다.

다른 위젯이나 상태 변화 등으로 위젯의 상태를 업데이트할 수 있습니다.

 

didUpdateWidget()

상태가 있는 위젯이 새로운 속성으로 업데이트 될 때 호출됩니다.

즉, 위젯이 새로운 구성 속성을 받아 다시 빌드되는 경우에 호출됩니다.

 

deactivate()

State가 플러터의 구성 트리로부터 제거되기 전에 호출됩니다.

다른 위젯으로 넘어가거나, 다른 페이지로 넘어갈 때 등의 예시가 있습니다.

아직은 다시 빌드가능합니다.

 

dispose()

State를 소멸시킵니다.

위젯을 없앨 때 할 작업을 여기에 작성하시면 됩니다.

disposed가 호출된 다음에는 다시 빌드할 수 없습니다.

 

한 눈에 보는 StatefulWidget의 생명주기

 

 

728x90
반응형