press will change (position may change) but scroll delta will not. - Release -> press will change (position may change) but scroll delta will not. - Move -> position will change but press and scroll delta will not. - Scroll -> scroll delta will change (position may change) but press will not. Note 2: The [position] values can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds. The [previousPosition] represents the position of the pointer offset to the current position of the pointer relative to the screen. This means that [position] and [previousPosition] can always be used to understand how much a pointer has moved relative to an element, even if that element is moving along with the changes to the pointer. For example, if a pointer touches a 1x1 pixel box in the middle, [position] will report a position of (0, 0) when dispatched to it. If the next event moves x position 5 pixels, [position] will report (5, 0) and [previousPosition] will report (0, 0). If the box moves all 5 pixels, and the next event represents the pointer moving along the x axis for 5 more pixels, [position] will again report (5, 0) and [previousPosition] will report (0, 0).' /> press will change (position may change) but scroll delta will not. - Release -> press will change (position may change) but scroll delta will not. - Move -> position will change but press and scroll delta will not. - Scroll -> scroll delta will change (position may change) but press will not. Note 2: The [position] values can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds. The [previousPosition] represents the position of the pointer offset to the current position of the pointer relative to the screen. This means that [position] and [previousPosition] can always be used to understand how much a pointer has moved relative to an element, even if that element is moving along with the changes to the pointer. For example, if a pointer touches a 1x1 pixel box in the middle, [position] will report a position of (0, 0) when dispatched to it. If the next event moves x position 5 pixels, [position] will report (5, 0) and [previousPosition] will report (0, 0). If the box moves all 5 pixels, and the next event represents the pointer moving along the x axis for 5 more pixels, [position] will again report (5, 0) and [previousPosition] will report (0, 0).'>

PointerInputChange

Class

Common
class PointerInputChange(
    val id: PointerId,
    val uptimeMillis: Long,
    val position: Offset,
    val pressed: Boolean,
    val pressure: Float,
    val previousUptimeMillis: Long,
    val previousPosition: Offset,
    val previousPressed: Boolean,
    isInitiallyConsumed: Boolean,
    val type: PointerType = PointerType.Touch,
    val scrollDelta: Offset = Offset.Zero,
)

Describes a change that has occurred for a particular pointer, as well as how much of the change has been consumed (meaning, used by a node in the UI).

The position represents the position of the pointer relative to the element that this PointerInputChange is being dispatched to.

Note 1: A PointerEvent's PointerEventType is the cause of an event and the associated PointerInputChange's properties reflecting that. Most of those are exclusive, in other words, a Press/Release PointerEventType will not cause a scrollDelta change and a Scroll PointerEventType will not cause a pressed or previousPressed change. However, either a a Scroll or a Press/Release may contain a position change in its PointerInputChanges. (You can imagine one finger moving while another is lifted up.)

Examples of PointerEventType and the associated PointerInputChange property changes:

  • Press -> press will change (position may change) but scroll delta will not.
  • Release -> press will change (position may change) but scroll delta will not.
  • Move -> position will change but press and scroll delta will not.
  • Scroll -> scroll delta will change (position may change) but press will not.

Note 2: The position values can be outside the actual bounds of the element itself meaning the numbers can be negative or larger than the element bounds.

The previousPosition represents the position of the pointer offset to the current position of the pointer relative to the screen.

This means that position and previousPosition can always be used to understand how much a pointer has moved relative to an element, even if that element is moving along with the changes to the pointer. For example, if a pointer touches a 1x1 pixel box in the middle, position will report a position of (0, 0) when dispatched to it. If the next event moves x position 5 pixels, position will report (5, 0) and previousPosition will report (0, 0). If the box moves all 5 pixels, and the next event represents the pointer moving along the x axis for 5 more pixels, position will again report (5, 0) and previousPosition will report (0, 0).

Parameters

idThe unique id of the pointer associated with this PointerInputChange.
uptimeMillisThe time of the current pointer event, in milliseconds. The start (0) time is platform-dependent
positionThe Offset of the current pointer event, relative to the containing element (values can be negative or larger than the element bounds).
pressedtrue if the pointer event is considered "pressed." For example, finger touching the screen or a mouse button is pressed pressed would be true.
pressureThe pressure of the of the pointer event
previousUptimeMillisThe uptimeMillis of the previous pointer event
previousPositionThe Offset of the previous pointer event, offset to the position and relative to the containing element.
previousPressedtrue if the pointer event was considered "pressed." For example , if a finger was touching the screen or a mouse button was pressed, previousPressed would be true.
isInitiallyConsumedwhether the change was consumed from the start or not. This value can change over time as change is propagated through the pointer handlers. To query the actual status of the change use isConsumed
typeThe device type that produced the event, such as mouse, or touch.git
scrollDeltaThe amount of scroll wheel movement in the horizontal and vertical directions.

Secondary Constructors

constructor(
    id: PointerId,
    uptimeMillis: Long,
    position: Offset,
    pressed: Boolean,
    previousUptimeMillis: Long,
    previousPosition: Offset,
    previousPressed: Boolean,
    isInitiallyConsumed: Boolean,
    type: PointerType = PointerType.Touch,
    scrollDelta: Offset = Offset.Zero,
) : this(
    id,
    uptimeMillis,
    position,
    pressed,
    pressure = 1.0f,
    previousUptimeMillis,
    previousPosition,
    previousPressed,
    isInitiallyConsumed,
    type,
    scrollDelta,
)
constructor(
    id: PointerId,
    uptimeMillis: Long,
    position: Offset,
    pressed: Boolean,
    previousUptimeMillis: Long,
    previousPosition: Offset,
    previousPressed: Boolean,
    consumed: ConsumedData,
    type: PointerType = PointerType.Touch,
) : this(
    id,
    uptimeMillis,
    position,
    pressed,
    pressure = 1.0f,
    previousUptimeMillis,
    previousPosition,
    previousPressed,
    consumed.downChange || consumed.positionChange,
    type,
    Offset.Zero,
)
internal constructor(
    id: PointerId,
    uptimeMillis: Long,
    position: Offset,
    pressed: Boolean,
    pressure: Float,
    previousUptimeMillis: Long,
    previousPosition: Offset,
    previousPressed: Boolean,
    isInitiallyConsumed: Boolean,
    type: PointerType,
    historical: List<HistoricalChange>,
    scrollDelta: Offset,
    originalEventPosition: Offset,
) : this(
    id,
    uptimeMillis,
    position,
    pressed,
    pressure,
    previousUptimeMillis,
    previousPosition,
    previousPressed,
    isInitiallyConsumed,
    type,
    scrollDelta,
) {
    _historical = historical
    this.originalEventPosition = originalEventPosition
}

Properties

Common
val historical: List<HistoricalChange>

Optional high-frequency pointer moves in between the last two dispatched events. Can be used for extra accuracy when touchscreen rate exceeds framerate.

Common
val isConsumed: Boolean

Indicates whether the change was consumed or not. Note that the change must be consumed in full as there's no partial consumption system provided.

Common

Deprecated use isConsumed and consume() pair of methods instead

val consumed: ConsumedData

Functions

fun consume()

Consume change event, claiming all the corresponding change info to the caller. This is usually needed when, button, when being clicked, consumed the "up" event so no other parents of this button could consume this "up" again.

"Consumption" is just an indication of the claim and each pointer input handler implementation must manually check this flag to respect it.

fun copy(
        id: PointerId = this.id,
        currentTime: Long = this.uptimeMillis,
        currentPosition: Offset = this.position,
        currentPressed: Boolean = this.pressed,
        previousTime: Long = this.previousUptimeMillis,
        previousPosition: Offset = this.previousPosition,
        previousPressed: Boolean = this.previousPressed,
        consumed: ConsumedData = this.consumed,
        type: PointerType = this.type,
    ): PointerInputChange
fun copy(
        id: PointerId = this.id,
        currentTime: Long = this.uptimeMillis,
        currentPosition: Offset = this.position,
        currentPressed: Boolean = this.pressed,
        previousTime: Long = this.previousUptimeMillis,
        previousPosition: Offset = this.previousPosition,
        previousPressed: Boolean = this.previousPressed,
        type: PointerType = this.type,
        scrollDelta: Offset = this.scrollDelta,
    ): PointerInputChange

Make a shallow copy of the PointerInputChange

NOTE: Due to the need of the inner contract of the PointerInputChange, this method performs a shallow copy of the PointerInputChange. Any consume call between any of the copies will consume any other copy automatically. Therefore, copy with the new isConsumed is not possible. Consider creating a new PointerInputChange

fun copy(
        id: PointerId = this.id,
        currentTime: Long = this.uptimeMillis,
        currentPosition: Offset = this.position,
        currentPressed: Boolean = this.pressed,
        previousTime: Long = this.previousUptimeMillis,
        previousPosition: Offset = this.previousPosition,
        previousPressed: Boolean = this.previousPressed,
        consumed: ConsumedData,
        type: PointerType = this.type,
        scrollDelta: Offset = this.scrollDelta,
    ): PointerInputChange
fun copy(
        id: PointerId = this.id,
        currentTime: Long = this.uptimeMillis,
        currentPosition: Offset = this.position,
        currentPressed: Boolean = this.pressed,
        pressure: Float = this.pressure,
        previousTime: Long = this.previousUptimeMillis,
        previousPosition: Offset = this.previousPosition,
        previousPressed: Boolean = this.previousPressed,
        type: PointerType = this.type,
        scrollDelta: Offset = this.scrollDelta,
    ): PointerInputChange

Make a shallow copy of the PointerInputChange

NOTE: Due to the need of the inner contract of the PointerInputChange, this method performs a shallow copy of the PointerInputChange. Any consume call between any of the copies will consume any other copy automatically. Therefore, copy with the new isConsumed is not possible. Consider creating a new PointerInputChange.

@ExperimentalComposeUiApi
    fun copy(
        id: PointerId = this.id,
        currentTime: Long = this.uptimeMillis,
        currentPosition: Offset = this.position,
        currentPressed: Boolean = this.pressed,
        previousTime: Long = this.previousUptimeMillis,
        previousPosition: Offset = this.previousPosition,
        previousPressed: Boolean = this.previousPressed,
        type: PointerType = this.type,
        historical: List<HistoricalChange>,
        scrollDelta: Offset = this.scrollDelta,
    ): PointerInputChange

Make a shallow copy of the PointerInputChange

NOTE: Due to the need of the inner contract of the PointerInputChange, this method performs a shallow copy of the PointerInputChange. Any consume call between any of the copies will consume any other copy automatically. Therefore, copy with the new isConsumed is not possible. Consider creating a new PointerInputChange.

fun copy(
        id: PointerId = this.id,
        currentTime: Long = this.uptimeMillis,
        currentPosition: Offset = this.position,
        currentPressed: Boolean = this.pressed,
        pressure: Float = this.pressure,
        previousTime: Long = this.previousUptimeMillis,
        previousPosition: Offset = this.previousPosition,
        previousPressed: Boolean = this.previousPressed,
        type: PointerType = this.type,
        historical: List<HistoricalChange> = this.historical,
        scrollDelta: Offset = this.scrollDelta,
    ): PointerInputChange

Make a shallow copy of the PointerInputChange

NOTE: Due to the need of the inner contract of the PointerInputChange, this method performs a shallow copy of the PointerInputChange. Any consume call between any of the copies will consume any other copy automatically. Therefore, copy with the new isConsumed is not possible. Consider creating a new PointerInputChange.