본문 바로가기
스파르타/Flutter

[Flutter] Widget 이해 - ( week 2 )

by bakcoding_sparta 2023. 4. 15.

StatelessWidget 

상태 변화가 없어 화면을 새로고침 할 필요가 없는 위젯이다.

상태란 화면상에 나타나는 정보를 뜻하며 변화가 없어 화면을 새로고침 할 필요가 없는 위젯이다.

즉 화면 내의 내용이 변화지 않는 위젯을 뜻한다.

 

class MyApp extends StatelessWidget {
	MyApp(); // 생성자 constructor
    @override	// 오버라이드 상속받은 함수를 재정의
    Widget build(BuildContext context) {
    	return Text("hello");
	}
}

extends StatelessWidget

StatelessWidget의 기능을 상속받는다.

 

MyApp()

생성자, 클래스 이름과 동일한 함수이다.

 

@override

상속받은 함수를 재정의해서 사용한다.

 

build()

화면에 보여줄 위젯을 반환한다. 내부에 정의를 통해 화면을 그린다.

 

MyApp은 StatelessWidget을 상속받아서 내부를 재정의해서 정적인 화면을 만든다.

 

import 'package:flutter/material.dart';

void main() {
  print("시작");
  runApp(const MyApp());
}

// StatelessWidget을 상속
class MyApp extends StatelessWidget {
  // 생성자
  const MyApp({Key? key}) : super(key: key);
  
  // build 라는 이름의 메서드(함수) 실행
  @override
  Widget build(BuildContext context) {
    print("build 호출");
    
    return const MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text(
            "hello Stateless Widget",
            style: TextStyle(fontSize: 35),
          ),
        ),
      ),
    );
  }
}

위 코드를 실행시키면 위와 같이 화면이 그려진다.

그려지는 방식을 살펴보면 우선 Dart 함수의 기본 동작대로 main 함수 내부의 코드부터 실행된다.

첫 줄의 print("시작")으로 콘솔창에 시작이라는 텍스트가 출력되고 다음 줄의 runApp(const MyApp()) 함수를 실행시켜 화면이 그려진다.

 

MyApp이 실행되면 build함수가 실행되고 print("build 호출")이 콘솔창에 출력되고 화면을 실제로 출력시키는 return으로 반환되는 위젯들이 그려지게 된다. 이 내부에 구현된 함수는 앞에서 학습했던 Scaffold 내부에 정의된 자식 위젯들로 화면을 그리게 된다. 이 MyApp 클래스의 호출로 생성되는 것들이 StatelessWidget이다.

 

StatefulWidget

화면상에 나타나는 정보가 변화가 있어 화면을 새로고침 할 필요가 있는 위젯 즉, 화면의 내용이 변하는 위젯이다.

 

// ignore_for_file: prefer_const_constructors
import 'package:flutter/material.dart';

void main() {
  print("시작");
  runApp(const MyApp());
}

// StatefulWidget을 상속
class MyApp extends StatefulWidget {
  // 생성자
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

// MyApp의 상태(State)를 나타내는 클래스
class _MyAppState extends State<MyApp> {
  int number = 1; // number가 1인 상태

  @override
  Widget build(BuildContext context) {
    print("build 호출");

    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text("$number", style: TextStyle(fontSize: 35)), // 변수를 문자열에 넣는 방법 template literal
        ),
        floatingActionButton: FloatingActionButton(
          child: Icon(Icons.add),
          onPressed: () {
            print("클릭");

            // setState : build 메서드(함수)를 다시 호출해서 화면 갱신
            setState(() {
              number += 1; // number를 1만큼 증가
            });
          },
        ),
      ),
    );
  }
}

 

기본적으로 두 개의 클래스로 구성된다.

 

MyApp

StatefulWidget을 상속한 클래스로 내부에서 MyApp() 생성자를 호출한다.

그리고 MyApp의 상태에 대한 정보는 _MyAppState()를 호출해서 화면을 그린다.

 

_MyAppState

상태 클래스로 State <MyApp>을 상속받는다. 여기서 실제로 화면을 그려지게 되는 재정의된 build 함수가 호출된다.

 

 

코드를 실행시켜보면 처음에 화면에는 1이 출력되는데 아래의 + 버튼을 클릭할 때마다 값이 1씩 증가하는 화면이 다시 그려지게 된다. 

 

onPressed 이벤트를 통해서 클릭이 될때마다 setState 함수가 호출되면서 build 함수가 다시 호출되면서 화면이 업데이트된다.