Dismissible๋ ๋ฆฌ์คํธ ์์ดํ
์ ์ข์ฐ๋ก ์ค์์ดํํด์ ์ญ์ , ๋ณด๊ด, ์๋ฃ ๊ฐ์ ์ก์
์ ์คํํ ์ ์๊ฒ ํด์ฃผ๋ Flutter ์์ ฏ์
๋๋ค.
โข
child: ํ๋ฉด์ ๋ณด์ด๋ ์ค์ ์ฝํ
์ธ
โข
background / secondaryBackground: ์ค์์ดํ ์ค ๋ค์์ ๋ณด์ด๋ ๋ฐฐ๊ฒฝ
โข
direction: ์ค์์ดํ ๋ฐฉํฅ ์ ํ
โข
confirmDismiss: ์ค์ ๋ก ์ ๊ฑฐํ๊ธฐ ์ ํ์ธ ๋ค์ด์ผ๋ก๊ทธ ๋ฑ ์ฒ๋ฆฌ
โข
onDismissed: ์ค์์ดํ ์๋ฃ ํ ์ญ์ ์ฒ๋ฆฌ์ ์ค๋ต๋ฐ ํ์ ๋ฑ์ ์ฌ์ฉ
Dismissible ์์ ฏ
์ธ์ ์ฌ์ฉํ๋๊ฐ
โข
ํ ์ผ ๋ชฉ๋ก (Todo List)
โข
์ด๋ฉ์ผ ์ฑ (์ฝ์ ์ฒ๋ฆฌ / ์ญ์ )
โข
์ฑํ
๋ฆฌ์คํธ (๋ํ ์ญ์ )
โข
๊ฐค๋ฌ๋ฆฌ ๋ฆฌ์คํธ (์ฌ์ง ์ ๊ฑฐ)
๊ธฐ๋ณธ ๊ตฌ์กฐ
Dismissible(
key: Key(item.id), // ๋ฐ๋์ ๊ณ ์ ๊ฐ
child: ListTile(
title: Text(item.title),
),
)
Dart
๋ณต์ฌ
ํต์ฌ ์์ฑ ์ ๋ฆฌ
child
child: ListTile(title: Text("ํ ์ผ"))
Dart
๋ณต์ฌ
background / secondaryBackground
background: Container(
color: Colors.red,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 20),
child: Icon(Icons.delete, color: Colors.white),
),
secondaryBackground: Container(
color: Colors.blue,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
child: Icon(Icons.archive, color: Colors.white),
),
Dart
๋ณต์ฌ
โข
background
์ผ์ชฝ โ ์ค๋ฅธ์ชฝ ์ค์์ดํ
โข
secondaryBackground
์ค๋ฅธ์ชฝ โ ์ผ์ชฝ ์ค์์ดํ
direction
direction: DismissDirection.horizontal
Dart
๋ณต์ฌ
์ต์
:
โข
horizontal
์ข์ฐ ๊ฐ๋ฅ
โข
vertical
์์๋ ๊ฐ๋ฅ
โข
endToStart
์ค๋ฅธ์ชฝ โ ์ผ์ชฝ
โข
startToEnd
์ผ์ชฝ โ ์ค๋ฅธ์ชฝ
confirmDismiss
confirmDismiss: (direction) async {
return await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("์ญ์ ํ์๊ฒ ์ต๋๊น?"),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text("์ทจ์"),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: Text("์ญ์ "),
),
],
),
);
},
Dart
๋ณต์ฌ
onDismissed
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("์ญ์ ๋์์ต๋๋ค")),
);
},
Dart
๋ณต์ฌ
์ ์ฒด ์์
ListView.builder(
itemCount: items.length,
itemBuilder: (context, index) {
final item = items[index];
return Dismissible(
key: Key(item.id),
background: Container(
color: Colors.red,
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: 20),
child: Icon(Icons.delete, color: Colors.white),
),
secondaryBackground: Container(
color: Colors.green,
alignment: Alignment.centerRight,
padding: EdgeInsets.only(right: 20),
child: Icon(Icons.check, color: Colors.white),
),
confirmDismiss: (direction) async {
return await showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text("์ ๋ง ์ญ์ ํ์๊ฒ ์ต๋๊น?"),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: Text("์ทจ์"),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: Text("์ญ์ "),
),
],
),
);
},
onDismissed: (direction) {
setState(() {
items.removeAt(index);
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text("${item.title} ์ญ์ ๋จ")),
);
},
child: ListTile(
title: Text(item.title),
),
);
},
);
Dart
๋ณต์ฌ
TIP
1. key๋ ์ ๋ ์ค๋ณต๋๋ฉด ์๋จ
key: Key(item.id)
Dart
๋ณต์ฌ
2. confirmDismiss ์์ด ์ญ์ ํ๋ฉด UX ์์ข์
3. ์ํ๊ด๋ฆฌ๋ ๊ฐ์ด ์ฐ๋ฉด ๋ ๊ฐ๋ ฅ
โข
Provider
โข
Riverpod
โข
Bloc
4. ๋ฐฉํฅ๋ณ ๋ค๋ฅธ ๊ธฐ๋ฅ ๊ตฌํ ๊ฐ๋ฅ
onDismissed: (direction) {
if (direction == DismissDirection.startToEnd) {
// ์๋ฃ ์ฒ๋ฆฌ
} else {
// ์ญ์ ์ฒ๋ฆฌ
}
}
Dart
๋ณต์ฌ





