일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- android
- appbar
- textview
- DART
- Kotlin
- tabbar
- LifeCycle
- 앱
- Compose
- 테스트
- data
- scroll
- 앱바
- Flutter
- viewmodel
- livedata
- intent
- activity
- ScrollView
- Navigation
- textfield
- binding
- CustomScrollView
- Button
- TEST
- Dialog
- 안드로이드
- Coroutines
- drift
- 계측
- 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]}"),
),
);
},
);
}
}
Dismissible class - widgets library - Dart API
A widget that can be dismissed by dragging in the indicated direction. Dragging or flinging this widget in the DismissDirection causes the child to slide out of view. Following the slide animation, if resizeDuration is non-null, the Dismissible widget anim
api.flutter.dev
'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 |