일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- activity
- livedata
- CustomScrollView
- textfield
- Compose
- viewmodel
- 계측
- appbar
- TEST
- 앱바
- tabbar
- Navigation
- 안드로이드
- LifeCycle
- binding
- 앱
- DART
- android
- textview
- 테스트
- intent
- Coroutines
- Button
- Dialog
- ScrollView
- scroll
- drift
- data
- Kotlin
- Flutter
- Today
- Total
Study Record
[Flutter] 스와이프로 위젯 삭제하기 (Dismissible) 본문
✍ Dismissible
주로 리스트 뷰(ListView, GridView 등)에서 사용자가 항목을 스와이프 모션으로 삭제하는 것을 가능하게 해주는 위젯이다.
Dismissible({
required Key key,
required Widget child,
Widget? background,
Widget? secondaryBackground,
Future Function(DismissDirection)? confirmDismiss,
void Function()? onResize,
void Function(DismissUpdateDetails)? onUpdate,
void Function(DismissDirection)? onDismissed,
DismissDirection direction = DismissDirection.horizontal,
Duration? resizeDuration = const Duration(milliseconds: 300),
Map dismissThresholds = const {},
Duration movementDuration = const Duration(milliseconds: 200),
double crossAxisEndOffset = 0.0,
DragStartBehavior dragStartBehavior = DragStartBehavior.start,
HitTestBehavior behavior = HitTestBehavior.opaque,
})
child 로 스와이프 할 위젯을 넣고 key 도 넣어준다. 만약 stateful 위젯이라면 삭제될 때마다 호출되는 onDismissed 를 사용하여 setState() 를 해주면서 데이터 관리도 해줘야 한다. background 는 스와이프 과정에서 원래 위젯이 밀려나면서 보이는 위젯이다.
다음 예시 코드는 플러터 api 공식 사이트에서 가져온 코드의 일부이다.
import 'package:flutter/material.dart';
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
List<int> items = List<int>.generate(100, (int index) => index);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
padding: const EdgeInsets.symmetric(vertical: 16),
itemBuilder: (BuildContext context, int index) {
return Dismissible(
background: Container(
color: Colors.green,
),
key: ValueKey<int>(items[index]),
onDismissed: (DismissDirection direction) {
setState(() {
items.removeAt(index);
});
},
child: ListTile(
title: Text(
'Item ${items[index]}',
),
),
);
},
);
}
}
😶 스와이프 방향 (direction)
direction 인자로 스와이프 방향을 정할 수 있다. 위, 아래와 관련된 방향이면 상위 스크롤 위젯의 방향이 좌, 우 방향의 스크롤이어야 하고, 좌, 우와 관련된 방향이면 스크롤 위젯은 위, 아래 방향의 스크롤이어야 한다.
direction | 설명 |
DismissDirection.up | 위로 스와이프 하면서 위젯 삭제하기 |
DismissDirection.down | 아래로 스와이프 하면서 위젯 삭제하기 |
DismissDirection.vertical | 위/아래로 스와이프 하면서 위젯 삭제하기 |
DismissDirection.startToEnd | 글자를 읽는 방향으로 위젯 삭제하기(left to right 라면 왼쪽에서 오른쪽으로 스와이프) |
DismissDirection.endToStart | 글자를 읽는 반대 방향으로 위젯 삭제하기(left to right 라면 오른쪽에서 왼쪽으로 스와이프) |
DismissDirection.horizontal | 좌우로 스와이프 하면서 위젯 삭제하기(왼 > 오 , 오 > 왼 둘 다 가능) |
예시 - DismissDirection.vertical , 스크롤 위젯 좌, 우)
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
List<int> items = List<int>.generate(100, (int index) => index);
@override
Widget build(BuildContext context) {
return Center(
child: Container(
height: 300.0,
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemCount: items.length,
padding: const EdgeInsets.symmetric(horizontal: 16),
itemBuilder: (BuildContext context, int index) {
return Dismissible(
direction: DismissDirection.vertical,
key: ValueKey<int>(items[index]),
onDismissed: (DismissDirection direction) {
setState(() {
items.removeAt(index);
});
},
child: Container(
color: Colors.greenAccent,
width: 250,
margin: EdgeInsets.only(right: 16.0, top: 16.0, bottom: 16.0),
child: Center(child: Text("$index")),
),
);
},
),
),
);
}
}
😶 background, secondaryBackground
위젯을 스와이프 했을 때 밀리면서 보여지는 위젯을 나타낸다. secondaryBackground 가 null 이 아니면 background 도 null 이 아니어야 한다.
① background == null && secondaryBackground == null 인 경우 , 스와이프 시 아무런 위젯도 보이지 않는다.
② backgounrd != null && secondaryBackground == null 인 경우, 양쪽으로 스와이프가 가능하다면 양쪽으로 스와이프 했을 때 똑같이 background 위젯이 보인다.
③ background != null && secondaryBackground != null 인 경우, background 는 아래 → 위, 왼쪽 → 오른쪽으로 스와이프 했을 때를 보여주고 secondaryBackground 는 위 → 아래, 오른쪽 → 왼쪽으로 스와이프 했을 때를 보여준다. 따라서 onDismissed 에서 direction 인자가 DismissDirection.startToEnd, DismissDirection.up 일 때는 background 위젯 쪽으로 스와이프 했을 때이고, direction 인자가 DismissDirection.endToStart, DismissDirection.down 일 때는 secondaryBackground 위젯 쪽으로 스와이프 했을 때이다.
예시 - ③ )
class MyStatefulWidget extends StatefulWidget {
const MyStatefulWidget({super.key});
@override
State<MyStatefulWidget> createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
List<int> items = List<int>.generate(100, (int index) => index);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: items.length,
padding: const EdgeInsets.symmetric(vertical: 16),
itemBuilder: (BuildContext context, int index) {
return Dismissible(
direction: DismissDirection.horizontal,
key: ValueKey<int>(items[index]),
onDismissed: (DismissDirection direction) {
setState(() {
if(direction == DismissDirection.startToEnd) {
print("background swipe");
} else if(direction == DismissDirection.endToStart) {
print("secondaryBackground swipe");
}
items.removeAt(index);
});
},
background: Container(
color: Colors.blue,
),
secondaryBackground: Container(
color: Colors.deepOrangeAccent,
),
child: ListTile(
title: Text("item ${items[index]}"),
),
);
},
);
}
}
'Flutter > widget_scrollView' 카테고리의 다른 글
[Flutter] 실시간 스크롤 offset 알아보기 (0) | 2023.03.16 |
---|---|
[Flutter] RefreshIndicator (새로 고침) (0) | 2023.03.09 |
[Flutter] 스크롤바 (Scrollbar) (0) | 2023.03.09 |
[Flutter] SliverPersistentHeader (스크롤 중 위젯 고정) (0) | 2023.03.09 |
[Flutter] CustomScrollView 에서 앱바 컨트롤하기(숨김, 고정 등) - SliverAppBar (0) | 2023.03.08 |