Виджет Dismissible
Виджет Dismissible оборачивает пункт списка
и требует уникальный key.
Направление задают через
DismissDirection
в параметре direction.
Подложку при смахивании рисуют в background
и secondaryBackground.
После жеста вызывают onDismissed.
Синтаксис
Dismissible(
key: ValueKey('abcde'),
onDismissed: (direction) {},
child: child,
)
Параметры
| Параметр | Описание |
|---|---|
key |
Уникальный ключ пункта в списке. Обязателен. |
child |
Дочерний виджет, который смахивают. |
direction |
Допустимые направления смахивания. Принимает
DismissDirection.
|
background |
Виджет под child при смахивании в стартовую сторону. |
onDismissed |
Вызывается, когда пункт убрали из списка. |
confirmDismiss |
Спрашивает, можно ли завершить смахивание. |
Пример
Давайте удалим строку свайпом влево:
import 'package:flutter/material.dart';
class SwipeList extends StatefulWidget
{
const SwipeList({super.key});
@override
State<SwipeList> createState() => _SwipeListState();
}
class _SwipeListState extends State<SwipeList>
{
final items = ['abcde', '12345'];
@override
Widget build(BuildContext context)
{
return ListView(
children: items.map((item) {
return Dismissible(
key: ValueKey(item),
direction: DismissDirection.endToStart,
background: Container(
color: Colors.red,
alignment: Alignment.centerRight,
padding: const EdgeInsets.only(right: 24),
child: const Icon(
Icons.delete,
color: Colors.white,
),
),
onDismissed: (_) {
setState(() {
items.remove(item);
});
},
child: ListTile(title: Text(item)),
);
}).toList(),
);
}
}
void main()
{
runApp(
MaterialApp(
home: Scaffold(
body: SwipeList(),
),
),
);
}
На экране два пункта; смахивание влево покажет красный фон и уберёт строку из списка.
Пример
Давайте спросим подтверждение перед удалением:
import 'package:flutter/material.dart';
class ConfirmSwipe extends StatefulWidget
{
const ConfirmSwipe({super.key});
@override
State<ConfirmSwipe> createState() => _ConfirmSwipeState();
}
class _ConfirmSwipeState extends State<ConfirmSwipe>
{
var visible = true;
@override
Widget build(BuildContext context)
{
if (!visible) {
return const Center(child: Text('empty'));
}
return Dismissible(
key: const ValueKey('row'),
confirmDismiss: (_) async {
return false;
},
onDismissed: (_) {},
child: const ListTile(title: Text('abcde')),
);
}
}
void main()
{
runApp(
MaterialApp(
home: Scaffold(
body: ConfirmSwipe(),
),
),
);
}
На экране пункт 'abcde'; после смахивания он вернётся, потому что confirmDismiss вернул false.
Смотрите также
-
перечисление
DismissDirection,
которое задаёт сторону смахивания -
виджет
Draggable,
который тащит виджет, а не убирает его -
виджет
GestureDetector,
который ловит onPanUpdate без удаления -
виджет
InteractiveViewer,
который масштабирует и сдвигает содержимое