Триггеры действий

Триггер действия — событие, которое происходит, когда пользователь работает с приложением: нажал кнопку, выбрал пункт списка, открыл страницу. Сработавший триггер запускает действие — то, чем приложение отвечает.

По сути триггеры — это «слушатели»: они следят за происходящим и сообщают приложению, когда пора реагировать.

Виды триггеров

Триггеры страницы и компонента

На уровне страницы и компонента есть триггеры инициализации, нажатия клавиш и другие события их жизненного цикла.

Подробности — на страницах Жизненный цикл страницы и Жизненный цикл компонента.

Базовые триггеры

  • On Tap — нажатие на виджет. Например, показать сообщение SnackBar при нажатии на кнопку.
  • On Double Tap — двойное нажатие. Обычный сценарий — приблизить изображение.
  • On Long Press — долгое нажатие. Им открывают контекстное меню: переименовать файл, удалить его.

Пример: показываем сообщение по нажатию кнопки через On Tap.

Триггеры отдельных виджетов

У некоторых виджетов есть собственные события:

  • On Submit — у TextField: пользователь нажал «отправить» или «готово».
  • On Page Load — у страницы: срабатывает при её загрузке; здесь запрашивают данные и обновляют содержимое.
  • On Phone Shake — у страницы: встряхивание устройства. В играх так, например, бросают кубик.
  • On Selected — у Dropdown, CheckboxGroup, Slider, RadioButton, ChoiceChips и RatingBar: изменение выбора.
  • On Page Swipe — у PageView: перелистывание.
  • On Toggle — у ToggleIcon: переключение.
  • On Completed, On Change — у PinCode: код введён полностью или изменён.
  • On Count Changed — у Count Controller: изменилось значение счётчика.

Жесты (Gesture Detector)

Триггеры жестов отвечают на касания, перетаскивания, свайпы и щипки. Например, onDoubleTap срабатывает на быстрое двойное нажатие — им удобно ставить «лайк» или приближать содержимое.

Эти триггеры появляются, когда вы добавляете действие на Container.

Стадии жеста

У жеста четыре стадии: начало, обновление, завершение и отмена. Понимание этой последовательности и отличает работающие жесты от тех, что срабатывают невпопад.

Жизненный цикл касания

У касания цикл простой: система следит, состоялось оно или было отменено.

  1. Down — палец коснулся экрана; срабатывает onTapDown.
  2. Up — палец оторвался от экрана; срабатывает onTapUp.
  3. Tap — после обоих событий срабатывает onTap: касание состоялось.
  4. Cancel — если палец слишком сдвинулся до отрыва, касание отменяется: сработает onTapCancel, а onTap — нет.

Как это выглядит по шагам:

tap-gesture-lifecycle

Жизненный цикл перетаскивания

Перетаскивание сложнее: движение отслеживается непрерывно.

  1. Start — пользователь начал вести палец; срабатывает, например, onHorizontalDragStart.
  2. Update — движение продолжается, и приложение получает актуальные данные: положение указателя, смещение. Здесь работает onHorizontalDragUpdate.
  3. End/Stop — палец оторвался, жест завершён: onHorizontalDragEnd.
  4. Cancel — жест прерван, например перехвачен другим жестом: onHorizontalDragCancel.

Как это выглядит по шагам:

lifecycle-stage.avif

Отмена перетаскивания

Порядок Start → Update → End/Stop соблюдается не всегда: отмена может случиться в любой момент, в том числе во время движения. Этим перетаскивание и отличается от касания.

Если горизонтальное перетаскивание перехватит другой жест, вместо onHorizontalDragEnd сработает onHorizontalDragCancel.

lifecycle-stage-cancel.avif

Полный список триггеров жестов

  • onDoubleTapCancel — двойное нажатие распознано, но не завершилось.
  • onDoubleTapDown — первое касание в последовательности двойного нажатия.
  • onForcePressEnd — нажатие с силой выше порога завершено.
  • onForcePressPeak — сила нажатия достигла пика.
  • onForcePressStart — сила нажатия превысила порог.
  • onForcePressUpdate — сила нажатия изменилась.
  • onHorizontalDragCancel — горизонтальное перетаскивание прервано.
  • onHorizontalDragDown — касание перед горизонтальным перетаскиванием.
  • onHorizontalDragEnd — горизонтальное перетаскивание завершено.
  • onHorizontalDragStart — горизонтальное перетаскивание началось.
  • onHorizontalDragUpdate — непрерывно во время горизонтального перетаскивания.
  • onLongPressCancel — долгое нажатие распознано, но не завершилось.
  • onLongPressDown — палец коснулся экрана с намерением долгого нажатия.
  • onLongPressEnd — долгое нажатие отпущено.
  • onLongPressMoveUpdate — палец движется во время долгого нажатия.
  • onLongPressStart — долгое нажатие началось после нужной выдержки.
  • onLongPressUp — палец отпущен после долгого нажатия.
  • onPanCancel — панорамирование (свободное перетаскивание) прервано.
  • onPanDown — касание перед панорамированием.
  • onPanEnd — панорамирование завершено.
  • onPanStart — панорамирование началось.
  • onPanUpdate — непрерывно во время панорамирования.
  • onScaleEnd — масштабирование (щипок) завершено.
  • onScaleStart — масштабирование началось.
  • onScaleUpdate — непрерывно во время масштабирования.
  • onSecondaryLongPress — долгое нажатие вторичным указателем (например, двумя пальцами).
  • onSecondaryLongPressCancel — такое нажатие распознано, но не завершилось.
  • onSecondaryLongPressDown — касание вторичным указателем перед долгим нажатием.
  • onSecondaryLongPressEnd — вторичное долгое нажатие отпущено.
  • onSecondaryLongPressMoveUpdate — движение вторичного указателя во время долгого нажатия.
  • onSecondaryLongPressStart — вторичное долгое нажатие началось.
  • onSecondaryLongPressUp — вторичное долгое нажатие завершено отпусканием.
  • onSecondaryTap — нажатие вторичным указателем.
  • onSecondaryTapCancel — такое нажатие распознано, но не завершилось.
  • onSecondaryTapDown — касание вторичным указателем.
  • onSecondaryTapUp — вторичный указатель отпущен.
  • onTapCancel — касание распознано, но не завершилось.
  • onTapDown — палец коснулся экрана.
  • onTapUp — палец отпущен после касания.
  • onTertiaryLongPress — долгое нажатие третичным указателем (например, тремя пальцами).
  • onTertiaryLongPressCancel — такое нажатие распознано, но не завершилось.
  • onTertiaryLongPressDown — касание третичным указателем перед долгим нажатием.
  • onTertiaryLongPressEnd — третичное долгое нажатие отпущено.
  • onTertiaryLongPressMoveUpdate — движение третичного указателя во время долгого нажатия.
  • onTertiaryLongPressStart — третичное долгое нажатие началось.
  • onTertiaryLongPressUp — третичное долгое нажатие завершено отпусканием.
  • onTertiaryTapCancel — третичное касание распознано, но не завершилось.
  • onTertiaryTapDown — касание третичным указателем.
  • onTertiaryTapUp — третичный указатель отпущен.
  • onVerticalDragCancel — вертикальное перетаскивание прервано.
  • onVerticalDragDown — касание перед вертикальным перетаскиванием.
  • onVerticalDragEnd — вертикальное перетаскивание завершено.
  • onVerticalDragStart — вертикальное перетаскивание началось.
  • onVerticalDragUpdate — непрерывно во время вертикального перетаскивания.

Данные жеста

Жест приносит не только сам факт события, но и данные — например, координаты точки, где происходит перетаскивание.

Что с ними делают:

  • Свой слайдер: по координатам двигают ползунок вдоль дорожки.
  • Масштабирование: данные жеста-щипка превращают в приближение и отдаление.
  • Отзывчивый интерфейс: анимация запускается ровно оттуда, куда пользователь нажал.

Данные доступны после добавления соответствующего триггера — через меню Set from Variable в редакторе действий:

  • Global Position X — координата X указателя относительно левого края экрана.
  • Global Position Y — координата Y относительно верхнего края экрана.
  • Local Position X — координата X относительно левого края виджета с триггером.
  • Local Position Y — координата Y относительно верхнего края этого виджета.
  • Delta X — горизонтальное смещение за время жеста.
  • Delta Y — вертикальное смещение.

access-xy-data

Ниже — пример, где всё это работает вместе.

Пример: свайп для удаления из корзины

Соберём привычное «смахнуть, чтобы удалить» целиком на жестах. Вот что получится:

Порядок действий:
  1. Заводим переменную offsetX для горизонтального смещения товара. Товар выводится в ListView и собран как переиспользуемый компонент, поэтому offsetX делаем переменной состояния компонента — тогда каждая позиция помнит своё смещение отдельно.

    component-state-variable.avif

  2. Чтобы товар двигался за пальцем, добавляем контейнеру с его вёрсткой анимацию сдвига (в разделе On Action Trigger). Duration ставим 0, а Final Position привязываем к переменной offsetX.

    инфо

    Запускать анимацию будем на каждое движение пальца — по событию onHorizontalDragUpdate (следующий шаг).

    add-animation.avif

  3. На основной контейнер вешаем триггер onHorizontalDragUpdate. Он срабатывает непрерывно, пока пользователь ведёт палец: обновляем offsetX по данным Delta X и запускаем анимацию. Так карточка едет за пальцем.

  4. Осталось решить, удалять товар или вернуть карточку на место. Для этого берём триггер onHorizontalDragEnd и проверяем, превысило ли offsetX значение 100. Если да — передаём индекс позиции наверх (действием Execute Callback), чтобы удалить товар из списка. Если нет — проигрываем анимацию в обратную сторону. В конце сбрасываем offsetX в 0, чтобы следующий свайп начался с чистого листа.

перевод официальной документации FlutterFlow

обновлено

ESC