[flutter] ExpansionPanelList 위젯의 확장/축소 상태 저장 및 로드하기

Flutter의 ExpansionPanelList 위젯은 확장 가능한 패널 목록을 만들어주는 강력한 도구입니다. 이 위젯은 사용자가 패널을 확장하거나 축소할 수 있는 기능을 제공합니다. 그러나 기본적으로 ExpansionPanelList는 화면을 다시 로드할 때마다 패널의 확장/축소 상태를 잃어버리게 됩니다. 이번 글에서는 ExpansionPanelList의 확장/축소 상태를 저장하고 로드하는 방법을 알아보겠습니다.

패널 상태 저장하기

  1. 먼저, 확장/축소 상태를 저장하기 위해 SharedPreferences 패키지를 설치해야 합니다. pubspec.yaml 파일에 다음 종속성을 추가해주세요:
dependencies:
  shared_preferences: ^2.0.6
  1. 이제 ExpansionPanelList 위젯을 구현하고 패널 상태를 저장해보겠습니다. 다음은 간단한 예제 코드입니다:
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

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

class _MyExpansionPanelListState extends State<MyExpansionPanelList> {
  List<Item> _items = [];
  
  @override
  void initState() {
    super.initState();
    _loadPanelState();
  }
  
  @override
  Widget build(BuildContext context) {
    return SingleChildScrollView(
      child: ExpansionPanelList(
        elevation: 1,
        expandedHeaderPadding: EdgeInsets.all(0),
        expansionCallback: (int index, bool isExpanded) {
          setState(() {
            _items[index].isExpanded = !isExpanded;
            _savePanelState();
          });
        },
        children: _items.map<ExpansionPanel>((Item item) {
          return ExpansionPanel(
            headerBuilder: (BuildContext context, bool isExpanded) {
              return ListTile(
                title: Text(item.headerValue),
              );
            },
            body: ListTile(
              title: Text(item.expandedValue),
            ),
            isExpanded: item.isExpanded,
          );
        }).toList(),
      ),
    );
  }
  
  Future<void> _savePanelState() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String> expandedItems = [];
    for (var item in _items) {
      if (item.isExpanded) {
        expandedItems.add(item.headerValue);
      }
    }
    await prefs.setStringList('expandedItems', expandedItems);
  }
  
  Future<void> _loadPanelState() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String> expandedItems = prefs.getStringList('expandedItems') ?? [];
    setState(() {
      _items = List<Item>.generate(expandedItems.length, (int index) {
        return Item(
          headerValue: expandedItems[index],
          expandedValue: 'Item ${expandedItems[index]} body',
        );
      });
    });
  }
}

class Item {
  Item({
    required this.expandedValue,
    required this.headerValue,
    this.isExpanded = false,
  });

  String expandedValue;
  String headerValue;
  bool isExpanded;
}

위의 코드에서 _items은 패널 목록을 나타내는 리스트입니다. _savePanelState 함수는 현재 확장된 패널들의 헤더 값을 저장합니다. _loadPanelState 함수는 저장된 헤더 값을 불러와 패널 목록을 업데이트합니다.

패널 상태 로드하기

이제 저장한 패널 상태를 로드해보겠습니다. Expanded 위젯을 사용하여 패널 목록을 감싸고 _savePanelState 함수를 호출하는 버튼을 추가해보겠습니다.

Expanded(
  child: MyExpansionPanelList(),
),
ElevatedButton(
  onPressed: () {
    _savePanelState();
  },
  child: Text('Save Panel State'),
),

버튼을 클릭하면 패널 상태가 저장되고 앱을 다시 실행해도 저장된 상태로 패널들이 확장되거나 축소됨을 확인할 수 있습니다.

결론

이번 글에서는 ExpansionPanelList 위젯의 확장/축소 상태를 저장하고 로드하는 방법을 알아보았습니다. SharedPreferences 패키지를 사용하여 패널의 상태를 저장하고 앱을 다시 실행해도 이전 상태를 유지할 수 있습니다. 개발 과정에서 유용하게 사용할 수 있는 기능이므로 활용해보시기 바랍니다.