Develop

Microgestures for 2D apps

Updated: Nov 4, 2026

Overview

Look and Pinch selection uses a thumb-and-index-finger pinch. Your app receives this selection as standard Android touch events. Microgesture swipes arrive as standard Android generic motion scroll events when routed to scrolling. The thumb-tap microgesture is not delivered to Android apps. No separate gesture API is involved.

How it works

Gestures that reach your app arrive like this:
GestureAndroid eventDelivered to
Pinch (Look and Pinch selection)
ACTION_DOWN, then ACTION_MOVE while held, then ACTION_UP on release
onTouchEvent()
Forward swipe, backward swipe, when routed to scrolling
ACTION_SCROLL carrying AXIS_VSCROLL
onGenericMotionEvent()
Left swipe, right swipe, when routed to scrolling
ACTION_SCROLL carrying AXIS_HSCROLL
onGenericMotionEvent()
Thumb tap
No event delivered to your app
N/A
The axis sign follows the device’s natural-scrolling setting:
SwipeAxisNatural scrolling onNatural scrolling off
Forward
AXIS_VSCROLL
Negative
Positive
Backward
AXIS_VSCROLL
Positive
Negative
Left
AXIS_HSCROLL
Positive
Negative
Right
AXIS_HSCROLL
Negative
Positive

Handle scrolling

Microgesture scrolls arrive as standard Android generic motion scroll events. Existing scrolling widgets such as ScrollView and HorizontalScrollView support ordinary scrolling with these events, so you can use them without a microgesture-specific handler. To implement custom scrolling in your own View, override onGenericMotionEvent() and handle ACTION_SCROLL.
In the override, read AXIS_VSCROLL for vertical scrolling or AXIS_HSCROLL for horizontal scrolling. The value is in scroll units, not pixels. Multiply it by ViewConfiguration.get(context).getScaledVerticalScrollFactor() or getScaledHorizontalScrollFactor(), then apply the result to your content’s scroll position. The delivered value already reflects the device’s natural-scrolling setting. Follow your view’s axis convention: ScrollView subtracts the vertical delta from its scroll position, and HorizontalScrollView adds the horizontal delta.
Return true for events your view handles. Pass every other event to the superclass. This statement, taken from the end of the AOSP method, delegates unhandled events to the superclass inside the callback:
        return super.onGenericMotionEvent(event);
For a framework example, see ScrollView.onGenericMotionEvent() in the AOSP source⁠. It shows axis reading, pixel conversion, scroll bounds, and event consumption.

Common mistakes and limits

  • Thumb tap delivers no event: do not build a feature or fallback that depends on it.
  • A swipe can yield more than one scroll event: accumulate the axis value per event; do not count events or treat one event as one action.
  • Standard Android APIs do not expose which gesture or hand produced the event: do not use pointer IDs or event counts to guess the hand or gesture; react only to the axis value and touch sequence delivered.
  • Honor the delivered sign: apply AXIS_VSCROLL and AXIS_HSCROLL as delivered, per the table above; do not invert or hardcode a direction.
  • Override both callbacks: a View handling only onTouchEvent() misses swipe scrolling. Override onGenericMotionEvent() too, and prefer standard Android scrolling widgets where they fit.