반응형
ExpansionPanel 의 정의
Expansion 즉, 확장할 수 있다는 뜻으로 아코디언처럼 펼쳐지는 리스트를 구현할 수 있습니다.
헤더와 본문이 있으며 확장하거나 축소할 수 있습니다. 패널 본체는 패널을 확장할 때만 볼 수 있습니다.
ExpansionPanel 는 어떻게 사용할까?
ExpansionPanel은 오직 ExpansionPanelList를 하위 항목으로 가집니다.
예제를 살펴보면 메인 위젯 안에 Appbar와 ExpansionPane로 구성되고, 정보를 받아오는 Item 클래스를 선언합니다. Item 클래스는 expandedValue와 headerValue, isExpanded로 구성하고 있는데, expandedValue는 아코디언리스트의 body안에 타이틀을 선언하고, headerValue는 헤더의 타이틀을, isExpanded는 드롭다운의 내부 내용을 상위 항목을 수평으로 채우도록 설정합니다. isExpanded가 참이면 내부 너비가 주변 컨테이너를 채우도록 확장됩니다. 기본은 false로 셋팅해놓습니다.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
/// 메인위젯입니다 - Appbar + ExpansionPanel
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
static const String _title = 'Flutter Code Sample';
@override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: const MyStatefulWidget(),
),
);
}
}
// ExpansionPanel 정보를 저장하는 공간입니다
class Item {
Item({
required this.expandedValue,
required this.headerValue,
this.isExpanded = false,
});
String expandedValue;
String headerValue;
bool isExpanded;
}
List<Item> generateItems(int numberOfItems) {
return List<Item>.generate(numberOfItems, (int index) {
return Item(
/// 헤더와 본문에 들어갈 내용 headerValue: 'Panel $index',
expandedValue: 'This is item number $index',
);
});
}
/// MyStatefulWidget은 stateful widget으로 하위위젯을 감쌉니다.
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({Key? key}) : super(key: key);
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
/// MyStatefulWidget의 개인 상태 클래스입니다.
/// SingleChildScrollView로 ExpansionPanelList를 감쌉니다. class _MyStatefulWidgetState extends State<MyStatefulWidget> {
/// 총 8개의 리스트 생성 final List<Item> _data = generateItems(8);
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Container(
child: _buildPanel(),
),
);
}
/// ExpansionPanelList
Widget _buildPanel() {
return ExpansionPanelList(
expansionCallback: (int index, bool isExpanded) {
setState(() {
_data[index].isExpanded = !isExpanded;
});
},
children: _data.map<ExpansionPanel>((Item item) {
return ExpansionPanel(
/// ExpansionPanel은 header와 body로 구성되어 있습니다. headerBuilder: (BuildContext context, bool isExpanded) {
return ListTile(
title: Text(item.headerValue),
);
},
body: ListTile(
title: Text(item.expandedValue),
subtitle:
const Text('To delete this panel, tap the trash can icon'),
trailing: const Icon(Icons.delete),
/// 아이콘 클릭 시 리스트를 삭제합니다. onTap: () { setState(() {
_data.removeWhere((Item currentItem) => item == currentItem);
});
}),
isExpanded: item.isExpanded,
);
}).toList(),
);
}
}
|
cs |
|
결과는 이렇습니다
헤더의 화살표를 클릭하면 body가 드롭다운되고 휴지통아이콘을 클릭하면 패널이 삭제됩니다.
참고자료
https://api.flutter.dev/flutter/material/ExpansionPanel-class.html
https://api.flutter.dev/flutter/material/ExpansionPanelList-class.html
반응형
'개발 > Flutter' 카테고리의 다른 글
[Flutter] Dialog에 SingleChildScrollView 사용하기 (0) | 2021.10.25 |
---|---|
[Flutter] 무조건 알아야할 Flutter의 기초 (0) | 2021.10.06 |
[Flutter] 버튼 클릭 시 잉크가 퍼지는 효과 : InkWell (0) | 2021.09.16 |
[Flutter] Getx 라우트 방식 (0) | 2021.09.14 |
[Flutter]이미지 연결이 안되는 현상 (0) | 2021.09.10 |
댓글