PointerInputModifierNode

Interface

Common
interface PointerInputModifierNode : DelegatableNode

A androidx.compose.ui.Modifier.Node that receives PointerInputChanges, interprets them, and consumes the aspects of the changes that it is react to such that other PointerInputModifierNodes don't also react to them.

This is the androidx.compose.ui.Modifier.Node equivalent of androidx.compose.ui.input.pointer.PointerInputFilter.

Properties

Common
val touchBoundsExpansion: TouchBoundsExpansion

Override this value to expand the touch bounds of this PointerInputModifierNode by the given value in align each edge. It only applies to this pointer input modifier and won't impact other pointer input modifiers on the same LayoutNode. Also note that a pointer in expanded touch bounds can't be intercepted by its parents and ancestors even if their interceptOutOfBoundsChildEvents returns true.

Functions

fun onPointerEvent(pointerEvent: PointerEvent, pass: PointerEventPass, bounds: IntSize)

Invoked when pointers that previously hit this PointerInputModifierNode have changed. It is expected that any PointerInputChanges that are used during this event and should not be considered valid to be used in other nodes should be marked as consumed by calling PointerInputChange.consume.

Parameters

pointerEventThe list of PointerInputChanges with positions relative to this PointerInputModifierNode.
passThe PointerEventPass in which this function is being called.
boundsThe width and height associated with this PointerInputModifierNode.
fun onCancelPointerInput()

Invoked to notify the handler that no more calls to PointerInputModifierNode will be made, until at least new pointers exist. This can occur for a few reasons:

  1. Android dispatches ACTION_CANCEL to Compose.
  2. This PointerInputModifierNode is no longer associated with a LayoutNode.
  3. This PointerInputModifierNode's associated LayoutNode is no longer in the composition tree.
fun interceptOutOfBoundsChildEvents(): Boolean

Intercept pointer input that children receive even if the pointer is out of bounds.

If true, and a child has been moved out of this layout and receives an event, this will receive that event. If false, a child receiving pointer input outside of the bounds of this layout will not trigger any events in this.

fun sharePointerInputWithSiblings(): Boolean

If false, then this PointerInputModifierNode will not allow siblings under it to respond to events. If true, this will have the first chance to respond and the next sibling under will then get a chance to respond as well. This trigger acts at the Layout level, so if any PointerInputModifierNodes on a Layout has sharePointerInputWithSiblings set to true then the Layout will share with siblings.

override fun onDensityChange()

Invoked when the density (pixels per inch for the screen) changes. This can impact the location of pointer input events (x and y) and can affect things like touch slop detection.

Developers will need to restart the gesture detection handling pointer input in order for the event locations to remain accurate.

The default implementation will do that by calling onCancelPointerInput. If you override this function, make sure to call super.onDensityChange or implement your own restarting logic.

SuspendingPointerInputModifierNode offers a more specific interface to allow only cancelling the coroutine for more control. See SuspendingPointerInputModifierNodeImpl for a concrete example.

fun onViewConfigurationChange()

Invoked when the view configuration (touch slop size, minimum touch target, tap timing) changes which means the composable UI the pointer input block is tied to has changed and the new UI might impact the location of pointer input events (x and y).

Developers will need to restart the gesture detection that handles pointer input in order for the events locations to remain accurate.

The default implementation will do that by calling onCancelPointerInput.

SuspendingPointerInputModifierNode offers a more specific interface to allow only cancelling the coroutine for more control. See SuspendingPointerInputModifierNodeImpl for a concrete example.

Code Examples

PointerInputModifierNodeSample

@ExperimentalComposeUiApi
@Composable
fun PointerInputModifierNodeSample() {
    class OnPointerEventNode(var callback: (PointerEvent) -> Unit) :
        PointerInputModifierNode, Modifier.Node() {
        override fun onPointerEvent(
            pointerEvent: PointerEvent,
            pass: PointerEventPass,
            bounds: IntSize,
        ) {
            if (pass == PointerEventPass.Initial) {
                callback(pointerEvent)
            }
        }
        override fun onCancelPointerInput() {
            // Do nothing
        }
    }
    data class PointerInputElement(val callback: (PointerEvent) -> Unit) :
        ModifierNodeElement<OnPointerEventNode>() {
        override fun create() = OnPointerEventNode(callback)
        override fun update(node: OnPointerEventNode) {
            node.callback = callback
        }
        override fun InspectorInfo.inspectableProperties() {
            name = "onPointerEvent"
            properties["callback"] = callback
        }
    }
    fun Modifier.onPointerEvent(callback: (PointerEvent) -> Unit) =
        this then PointerInputElement(callback)
}