PointerInputModifierNode

Known direct subclasses
SuspendingPointerInputModifierNode

Extends PointerInputModifierNode with a handler to execute asynchronously when an event occurs and a function to reset that handler (cancels the existing coroutine and essentially resets the handler's execution).


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.

import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.PointerEvent
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.PointerInputModifierNode
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.unit.IntSize

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)

Summary

Public functions

open Boolean

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

Cmn
Unit

Invoked to notify the handler that no more calls to PointerInputModifierNode will be made, until at least new pointers exist.

Cmn
open Unit

Invoked when the density (pixels per inch for the screen) changes.

Cmn
Unit
onPointerEvent(
    pointerEvent: PointerEvent,
    pass: PointerEventPass,
    bounds: IntSize
)

Invoked when pointers that previously hit this PointerInputModifierNode have changed.

Cmn
open Unit

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).

Cmn
open Boolean

If false, then this PointerInputModifierNode will not allow siblings under it to respond to events.

Cmn

Public properties

open TouchBoundsExpansion

Override this value to expand the touch bounds of this PointerInputModifierNode by the given value in align each edge.

Cmn

Inherited functions

From androidx.compose.ui.node.DelegatableNode
open Unit

Invoked when the layout direction changes for this node.

Cmn

Inherited properties

From androidx.compose.ui.node.DelegatableNode
Modifier.Node

A reference of the Modifier.Node that holds this node's position in the node hierarchy.

Cmn

Public functions

interceptOutOfBoundsChildEvents

open 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.

onCancelPointerInput

fun onCancelPointerInput(): Unit

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.

onDensityChange

open fun onDensityChange(): Unit

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.

onPointerEvent

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

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
pointerEvent: PointerEvent

The list of PointerInputChanges with positions relative to this PointerInputModifierNode.

pass: PointerEventPass

The PointerEventPass in which this function is being called.

bounds: IntSize

The width and height associated with this PointerInputModifierNode.

onViewConfigurationChange

open fun onViewConfigurationChange(): Unit

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.

sharePointerInputWithSiblings

open 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.

Public properties

touchBoundsExpansion

open val touchBoundsExpansionTouchBoundsExpansion

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.