본문 바로가기
Flutter + Dart/Flutter + Dart 공부

Widget의 종류

by GREEN나무 2025. 5. 7.
728x90

//widgets/framework.dart 
abstract class Widget {}
abstract class StatelessWidget extends Widget {}
abstract class StatefulWidget extends Widget {}
abstract class RenderObjectWidget extends Widget {}
abstract class InheritedWidget extends Widget {}  

 

1. Widget

  • 정의: Flutter에서 화면에 그려지는 모든 요소의 최상위 추상 클래스.
  • 특징:
    1. 불변(immutable) 객체로, 프로퍼티가 바뀌면 새로운 위젯 인스턴스를 생성
    2. 트리 구조를 이루며, 부모→자식으로 위젯 트리가 구성
  • 쓰임새:
    • 모든 커스텀 위젯은 이 클래스를 직접 또는 간접적으로 상속
    • build() 메서드를 구현하지 않으며, 서브클래스에서 구체화

2. StatelessWidget

  • 정의: 내부 상태를 가지지 않는 위젯의 기반 클래스
  • 특징:
    1. 상태 관리 없음. 입력(constructor로 받은 값)이 바뀔 때만 다시 그려짐
    2. build(BuildContext context) 메서드만 오버라이드
  • 사용 예:
    • 고정된 레이아웃이나, 부모로부터 받은 데이터만 표시할 때
  • 단계별 구현:
    1. 클래스 선언: class MyLabel extends StatelessWidget
    2. 생성자에서 필요한 속성 선언
    3. @override Widget build(...) 에서 Text, Container 등 조합
class MyLabel extends StatelessWidget {
  final String text;
  MyLabel(this.text);

  @override
  Widget build(BuildContext context) {
    return Text(text, style: TextStyle(fontSize: 18));
  }
}

3. StatefulWidget

  • 정의: 내부 상태(State)를 가지고, 상태 변화 시 UI를 갱신할 수 있는 위젯
  • 특징:
    1. 두 개의 클래스로 구성: StatefulWidget 본체와 State<T>
    2. State 에서 initState(), dispose(), setState() 등 라이프사이클 활용
  • 사용 예:
    • 버튼 클릭, 애니메이션, 네트워크 응답 등 동적 콘텐츠
  • 단계별 구현:
    1. class Counter extends StatefulWidget 선언
    2. @override State<Counter> createState() => _CounterState();
    3. _CounterState 클래스 안에서 int _count, initState(), build(), setState() 활용
class Counter extends StatefulWidget {
  @override
  _CounterState createState() => _CounterState();
}

class _CounterState extends State<Counter> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Count: $_count'),
        ElevatedButton(
          onPressed: () => setState(() => _count++),
          child: Text('증가'),
        ),
      ],
    );
  }
}

4. RenderObjectWidget

  • 정의: 직접 렌더링 로직(RenderObject)을 연결하는 저수준(Low-level) 위젯
  • 특징:
    1. 고성능 커스텀 레이아웃·페인팅 구현 시 사용
    2. createRenderObject() 와 updateRenderObject() 메서드를 구현
  • 사용 예:
    • 완전히 새로운 레이아웃 알고리즘이 필요할 때
    • 직접 캔버스에 그리거나 복잡한 충돌 감지 로직 등
  • 단계별 구현:
    1. class MyBox extends RenderObjectWidget 선언
    2. RenderBox createRenderObject(BuildContext) 구현
    3. RenderBox 서브클래스에서 performLayout(), paint() 오버라이드

5. InheritedWidget

  • 정의: 자식 위젯에게 데이터를 효율적으로 공급하는 특수 위젯
  • 특징:
    1. 트리 하위 모든 위젯이 of(context) 로 접근 가능
    2. updateShouldNotify() 통해 갱신조건 판단
  • 사용 예:
    • 테마, 로케일, 로그인 사용자 정보 등 전역 데이터 공유
  • 단계별 구현:
    1. class MyConfig extends InheritedWidget 선언
    2. final 프로퍼티에 공유 데이터 저장
    3. static MyConfig of(BuildContext) 메서드 제공
    4. updateShouldNotify(old) 에서 변경 여부 반환
class MyConfig extends InheritedWidget {
  final String apiUrl;
  const MyConfig({required this.apiUrl, required Widget child}) : super(child: child);

  static MyConfig of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<MyConfig>()!;
  }

  @override
  bool updateShouldNotify(MyConfig old) => apiUrl != old.apiUrl;
}