Flutter

[Flutter] Flutter의 위젯과 Element 트리 그리고 Key의 역할과 사용 방법

미로910 2024. 11. 14. 12:58

  • Flutter는 각 위젯마다 Element 객체를 생성해 트리 구조를 만듭니다.
  • Element는 위젯의 타입, 위치 정보를 저장하고 자식 Element와 연결되어 전체 트리를 구성합니다
구현할 화면

 

코드
import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: MyHomePage()));
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final listTile = <Tile>[
    Tile(key: ValueKey('파란색'), color: Colors.blue, name: '파란색 타일'),
    Tile(key: ValueKey('빨간색'), color: Colors.red, name: '빨간색 타일'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('키가 없는 위젯을 만들어 보기'),
      ),
      body: Center(
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: listTile,
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: swapTiles,
        child: Icon(Icons.swap_horiz),
      ),
    );
  } // end of build()

  // 첫번째 타일과 두번째 타일을 교환하는 기능
  void swapTiles(){
    // ['파란색타일', '빨간색타일']
    setState(() {
      // // 첫 번째 타일을 제거하고 그 타일을 반환하는 기능
      // // ['빨간색타일']
      // var removedTile = listTile.removeAt(0);
      // // 제거된 타일을 두 번째 위치로 삽입 하자.
      // listTile.insert(1, removedTile);

      // 축약해서 코드 작성
      listTile.insert(1, listTile.removeAt(0));

    });
  }

} // end of state class

class Tile extends StatefulWidget {
  final Color color; // 타일에 색상
  final String name; // 타일에 이름

  // Key 속성을 추가해서 부모 클래스(Sate) 고유 식별자를 보장한다.
  const Tile({required Key key,
    required this.color, required this.name}) : super(key: key);

  @override
  State<Tile> createState() => _TileState();
}

// 커스텀 Tile 클래스의 상태 관리 클래스 입니다.
class _TileState extends State<Tile> {
  // State 멤버 변수 widget 이런 멤버 변수를 제공해서 상위 클래스에 접근 할 수 ㅇㅆ도록 만들어 주고 있다.
  Color? currentColor; //현재 타일에 색상을 지정

  @override
  void initState() {
    super.initState();
    // 부모 클래스 변수에 접근해서 값을 가져 옴
    currentColor = widget.color;
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      color: currentColor,
      width: 100,
      height: 100,
      alignment: Alignment.center,
      child: Text(
        widget.name,
        style: const TextStyle(
          color: Colors.white,
          fontWeight: FontWeight.bold,
        ),
      ),
    );
  }
}

State 클래스는 StatefulWidget과 연결된 상태 관리 클래스로, Flutter에서 위젯의 상태를 저장하고 변경하는 역할을 담당합니다. State 클래스는 부모 Widget에 연결된 속성이나 값에 직접 접근할 수 없기 때문에, widget 객체를 통해 부모 Widget의 속성 값을 사용할 수 있습니다.

 

Flutter는 위젯 트리에서 동일한 타입의 위젯을 재사용합니다. 위젯의 순서가 바뀌거나 새로 추가되는 경우, 이전 상태를 그대로 이어가게 되어 UI 버그가 발생할 수 있습니다. 예를 들어, 리스트에서 순서를 바꾸면 Flutter는 기존의 상태를 재사용하여 버그가 발생할 수 있습니다.

💡| Key를 사용하지 않아 위젯을 교환할 때 상태가 제대로 업데이트되지 않음

 

실행 화면_____