[flutter] ExpansionPanel에서 텍스트 입력 필드 추가하기

Flutter의 ExpansionPanel 위젯은 사용자가 클릭하여 컨텐츠를 확장하거나 축소할 수 있는 펼침 패널을 제공합니다. 이 위젯은 자체적인 기능을 가지고 있지만, 때로는 사용자에게 텍스트를 입력할 수 있는 필드를 추가하고 싶을 수도 있습니다.

이 문제를 해결하기 위해 ExpansionPanel 위젯에 텍스트 입력 필드를 추가하는 방법을 알아보겠습니다.

ExpansionPanel 위젯 정의하기

먼저 ExpansionPanel 위젯을 정의해야합니다. ExpansionPanel은 ExpansionPanelList 위젯 내에서 사용되며 각각의 패널은 ExpansionPanel 위젯으로 구성됩니다.

ExpansionPanel(
  headerBuilder: (BuildContext context, bool isExpanded) {
    return Container(
      child: Text('펼치기 패널 헤더'),
    );
  },
  body: Column(
    children: [
      TextFormField(
        decoration: InputDecoration(
          labelText: '텍스트 입력 필드',
        ),
      ),
    ],
  ),
  isExpanded: false,
);

위의 예제에서 headerBuilder는 패널의 헤더를 정의하는 메서드입니다. body는 패널이 펼쳐졌을 때 보여지는 내용을 정의합니다. 여기에 TextFormField 위젯을 추가하여 텍스트 입력 필드를 생성합니다.

ExpansionPanelList 생성하기

ExpansionPanelList를 사용하면 여러 개의 ExpansionPanel을 관리할 수 있습니다. 아래의 예제에서는 ExpansionPanelListBuilder라는 도우미 메서드를 사용하여 ExpansionPanelList를 생성합니다.

ExpansionPanelList(
  elevation: 2,
  expandedHeaderPadding: EdgeInsets.zero,
  expansionCallback: (int index, bool isExpanded) {
    setState(() {
      _expandedPanels[index] = !isExpanded;
    });
  },
  children: _panels.map<ExpansionPanel>((ExpansionPanel panel) {
    return panel;
  }).toList(),
);

expansionCallback은 패널이 펼쳐졌는지 여부를 관리하기 위한 콜백 함수입니다. 이를 통해 패널의 상태를 업데이트하고 setState를 호출하여 UI를 다시 그립니다.

전체 코드

다음은 위 작업을 모두 포함한 전체 코드입니다.

class MyExpansionPanelList extends StatefulWidget {
  @override
  _MyExpansionPanelListState createState() => _MyExpansionPanelListState();
}

class _MyExpansionPanelListState extends State<MyExpansionPanelList> {
  List<ExpansionPanel> _panels = [];

  @override
  void initState() {
    super.initState();
    _panels = _generatePanels();
  }

  List<ExpansionPanel> _generatePanels() {
    return List.generate(3, (int index) {
      return ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Container(
            child: Text('펼치기 패널 헤더 $index'),
          );
        },
        body: Column(
          children: [
            TextFormField(
              decoration: InputDecoration(
                labelText: '텍스트 입력 필드',
              ),
            ),
          ],
        ),
        isExpanded: false,
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ExpansionPanelList(
        elevation: 2,
        expandedHeaderPadding: EdgeInsets.zero,
        expansionCallback: (int index, bool isExpanded) {
          setState(() {
            _panels[index] = !isExpanded;
          });
        },
        children: _panels.map<ExpansionPanel>((ExpansionPanel panel) {
          return panel;
        }).toList(),
      ),
    );
  }
}

텍스트 필드를 포함하는 ExpansionPanel을 만들기위해 ExpansionPanel 위젯의 body에 TextFormField를 추가했습니다. ExpansionPanelList를 사용하여 여러 분야의 패널을 관리하고 전체 코드는 MyExpansionPanelList라는 StatefulWidget에서 구현되었습니다.

이제 Flutter 앱에서 ExpansionPanelList에 텍스트 입력 필드를 추가 할 수 있습니다.