[flutter] ExpansionPanel에서 외부 데이터를 불러와서 동적으로 패널 생성하기

이번 포스트에서는 Flutter 앱에서 ExpansionPanel 위젯에 외부 데이터를 불러와서 동적으로 패널을 생성하는 방법을 알아보겠습니다.

ExpansionPanel 위젯은 Flutter에서 아코디언 스타일의 패널을 만들기 위해 사용됩니다. 각 패널은 머리글과 내용으로 구성되어 있으며, 머리글을 클릭하면 해당 패널의 내용이 펼쳐지거나 닫힙니다.

우리의 목표는 ExpansionPanelList를 사용하여 동적으로 패널을 생성하는 것입니다. 이를 위해 외부 데이터를 불러오고, 각 데이터 항목에 대해 ExpansionPanel을 생성하여 리스트에 추가합니다.

단계 1: 외부 데이터 가져오기

먼저, 사용할 외부 데이터를 가져와야 합니다. 이 데이터는 List 형태로 구성되어야 하며, 각 항목은 머리글과 내용을 포함해야 합니다.

List<Map<String, dynamic>> panelData = [
  {
    'header': '패널 1',
    'body': '패널 1의 내용',
  },
  {
    'header': '패널 2',
    'body': '패널 2의 내용',
  },
  // 추가 데이터 항목...
];

위와 같이 panelData 변수에 내용을 저장합니다. 각 항목은 맵 형태로 구성되어 있으며, ‘header’와 ‘body’ 키를 사용하여 머리글과 내용을 표시합니다.

단계 2: ExpansionPanelList 생성하기

이제 ExpansionPanelList를 생성하여 동적으로 패널을 생성합니다. ExpansionPanelList 위젯은 ExpansionPanel을 포함하는 리스트를 만들기 위해 사용됩니다.

ExpansionPanelList(
  elevation: 1,
  expandedHeaderPadding: EdgeInsets.all(0),
  elevation: 1,
  expansionCallback: (int index, bool isExpanded) {
    setState(() {
      panelData[index]['isExpanded'] = !isExpanded;
    });
  },
  children: panelData.map<ExpansionPanel>((Map<String, dynamic> panel) {
    return ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) {
        return ListTile(
          title: Text(panel['header']),
        );
      },
      body: ListTile(
        title: Text(panel['body']),
      ),
      isExpanded: panel['isExpanded'],
    );
  }).toList(),
)

위의 코드에서, elevation은 패널의 그림자 높이를 설정하며, expandedHeaderPadding은 패널 헤더의 패딩을 설정합니다. expansionCallback은 패널 헤더를 클릭했을 때 호출될 콜백 함수입니다. 이 함수에서 패널의 확장 상태를 변경하여 패널이 펼쳐지거나 닫히도록 합니다.

ExpansionPanelList의 children 속성에는 map 함수를 사용하여 panelData의 각 항목에 대해 ExpansionPanel을 생성합니다. headerBuilder와 body는 각각 패널의 머리글과 내용을 생성하는 빌더 함수입니다. isExpanded는 패널의 초기 확장 상태를 나타내는 불리언 값입니다.

단계 3: ExpansionPanelList 사용하기

위의 코드를 StatefulWidget의 build 메서드에 추가하여 ExpansionPanelList를 사용합니다.

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<Map<String, dynamic>> panelData = [
    {
      'header': '패널 1',
      'body': '패널 1의 내용',
    },
    {
      'header': '패널 2',
      'body': '패널 2의 내용',
    },
    // 추가 데이터 항목...
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Expansion Panel 예제'),
      ),
      body: SingleChildScrollView(
        child: ExpansionPanelList(
          elevation: 1,
          expandedHeaderPadding: EdgeInsets.all(0),
          elevation: 1,
          expansionCallback: (int index, bool isExpanded) {
            setState(() {
              panelData[index]['isExpanded'] = !isExpanded;
            });
          },
          children: panelData.map<ExpansionPanel>((Map<String, dynamic> panel) {
            return ExpansionPanel(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return ListTile(
                  title: Text(panel['header']),
                );
              },
              body: ListTile(
                title: Text(panel['body']),
              ),
              isExpanded: panel['isExpanded'],
            );
          }).toList(),
        ),
      ),
    );
  }
}

위의 코드에서는 panelData 변수를 State 클래스의 멤버 변수로 선언하여 데이터를 관리합니다. setState 함수를 호출하여 화면을 다시 그려서 패널의 확장 상태가 변경되었음을 알립니다.

위의 코드를 실행하면 ExpansionPanelList가 화면에 표시되며, 각 패널의 머리글을 클릭하여 내용을 펼칠 수 있습니다. 이러한 방식으로 외부 데이터를 불러와서 동적으로 ExpansionPanel을 생성하는 것이 가능합니다.

이 문서는 Flutter ExpansionPanelList 공식 문서를 참고하여 작성되었습니다.