Сегодня поговорим про виджеты для обработки нажатий и жестов на экране во Flutter-приложениях. Самые распространенные — GestureDetector, InkWell и Listener. Разберем, чем они отличаются и в каком случае лучше использовать тот или иной виджет.
GestureDetector — самый универсальный виджет. Он имеет широкий спектр отслеживания жестов на экране. С его помощью можно обработать как простые одинарные или двойные нажатия (onTap, onDoubleTap), так и более сложные действия, например, свайпы и жесты масштабирования (onHorizontalDrag, onVerticalDrag, onPan, onScale).
Кроме того, что GestureDetector дает возможность отслеживать жесты, некоторые колбэки также возвращают объекты дополнительных сведений о манипуляции пользователя. Например, колбэк
onHorizontalDragUpdate вызывается при горизонтальном свайпе и дает доступ к объекту DragUpdateDetails. В нем содержатся данные о позиции указателя и координатах смещения. Это может быть полезно, когда необходимо отслеживать, где именно был выполнен свайп. Визуально виджет никак не реагирует на жесты и не требует обязательной обертки в Material-виджет.
GestureDetector(
onTap: () => print('Tapped!'),
onLongPress: () => print('Long Pressed!'),
onScaleUpdate: (details) => print(
'Scale Updated: ${details.scale}',
),
onHorizontalDragUpdate: (details) => print(
'Drag Updated: ${details.delta}',
),
);
InkWell — наиболее простой виджет из сегодняшнего списка. Он позволяет отслеживать только самые простые нажатия (onTap, onDoubleTap, onLongPress).
Как и GestureDetector, некоторые колбэки возвращают основную информацию о произведенном жесте.
Но в отличие от GestureDetector, отображает анимацию нажатия. Этот визуальный эффект легко кастомизировать. InkWell требует обязательного наличия любого Material-виджета в качестве родителя.
InkWell(
onTap: () => print('Tapped!'),
onTapUp: (details) => print('Tap Up: ${details.localPosition}'),
hoverDuration: const Duration(milliseconds: 100),
highlightColor: Colors.red,
child: Container(
padding: const EdgeInsets.all(16.0),
child: const Text('Tap me!'),
),
);
Listener — низкоуровневый виджет для обработки событий указателя.
Его основное отличие от GestureDetector и InkWell в том, что он не отслеживает сами жесты, не распознает их отличия друг от друга. Он работает непосредственно с указателем, дает полные данные о его поведении.
Как и GestureDetector, виджет не дает никакого визуального отклика.
Listener(
onPointerDown: (event) => print('Pointer Down: ${event.localPosition}'),
onPointerPanZoomStart: (event) => print('Pointer Pan Zoom Start: ${event.localPosition}'),
onPointerMove: (event) => print('Pointer Move: ${event.localPosition}'),
);
Подведем итог — когда же применять каждый из них?
✔️InkWell используйте для обработки самых простых нажатий, когда требуется минимум контроля над действием, а также когда в интерфейсе необходима визуальная анимация жеста.
✔️GestureDetector будет полезен при отслеживании нестандартных жестов, например, свайпов в каком-то конкретном направлении или масштабировании. Также его можно использовать вместо InkWell, когда не требуется показывать никакие визуальные эффекты.
✔️Listener применяйте для самых специфических задач. Он отлично подойдет, когда вам потребуется отслеживать события указателя в нестандартных движениях пользователя. Если GestureDetector не сможет помочь в вашей задаче, Listener точно справится.
