TouchInjectionScope


The receiver scope of the touch input injection lambda from performTouchInput.

The functions in TouchInjectionScope can roughly be divided into two groups: full gestures and individual touch events. The individual touch events are: down, move and friends, up, cancel and advanceEventTime. Full gestures are all the other functions, like click, doubleClick, swipe, etc. These are built on top of the individual events and serve as a good example on how you can build your own full gesture functions.

A touch gesture is started with a down event, followed by a sequence of move events and finally an up event, optionally combined with more sets of down and up events for multi-touch gestures. Most methods accept a pointerId to specify which pointer (finger) the event applies to. Movement can be expressed absolutely with moveTo and updatePointerTo, or relative to the current pointer position with moveBy and updatePointerBy. The moveTo/By methods enqueue an event immediately, while the updatePointerTo/By methods don't. This allows you to update the position of multiple pointers in a single move event for multi-touch gestures. Touch gestures can be cancelled with cancel. All events, regardless the method used, will always contain the current position of all pointers.

The entire event injection state is shared between all perform.*Input methods, meaning you can continue an unfinished touch gesture in a subsequent invocation of performTouchInput or performMultiModalInput. Note however that while the pointer positions are retained across invocation of perform.*Input methods, they are always manipulated in the current node's local coordinate system. That means that two subsequent invocations of performTouchInput on different nodes will report a different currentPosition, even though it is actually the same position on the screen.

All events sent by these methods are batched together and sent as a whole after performTouchInput has executed its code block. Because gestures don't have to be defined all in the same performTouchInput block, keep in mind that while the gesture is not complete, all code you execute in between these blocks will be executed while imaginary fingers are actively touching the screen. The events sent as part of the same batch will not be interrupted by recomposition, however, if a gesture spans multiple performTouchInput blocks it is important to remember that recomposition, layout and drawing could take place during the gesture, which may lead to events being injected into a moving target. As pointer positions are manipulated in the current node's local coordinate system, this could lead to issues caused by the fact that part of the gesture will take effect before the rest of the events have been enqueued.

Example of performing a click:

import androidx.compose.ui.test.click
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTouchInput

composeTestRule.onNodeWithTag("myComponent").performTouchInput { click() }

Example of performing a swipe up:

import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTouchInput
import androidx.compose.ui.test.swipeUp

composeTestRule.onNodeWithTag("myComponent").performTouchInput { swipeUp() }

Example of performing an L-shaped gesture:

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTouchInput

composeTestRule.onNodeWithTag("myComponent").performTouchInput {
    down(topLeft)
    moveTo(topLeft + percentOffset(0f, .1f))
    moveTo(topLeft + percentOffset(0f, .2f))
    moveTo(topLeft + percentOffset(0f, .3f))
    moveTo(topLeft + percentOffset(0f, .4f))
    moveTo(centerLeft)
    moveTo(centerLeft + percentOffset(.1f, 0f))
    moveTo(centerLeft + percentOffset(.2f, 0f))
    moveTo(centerLeft + percentOffset(.3f, 0f))
    moveTo(centerLeft + percentOffset(.4f, 0f))
    moveTo(center)
    up()
}
See also
InjectionScope

Summary

Public functions

Unit
cancel(delayMillis: Long)

Sends a cancel event delayMillis after the last sent event to cancel the current gesture.

Cmn
Offset?
currentPosition(pointerId: Int)

Returns the current position of the given pointerId.

Cmn
open Unit
down(position: Offset)

Sends a down event for the default pointer at position on the associated node.

Cmn
Unit
down(pointerId: Int, position: Offset)

Sends a down event for the pointer with the given pointerId at position on the associated node.

Cmn
Unit
move(delayMillis: Long)

Sends a move event delayMillis after the last sent event without updating any of the pointer positions.

Cmn
open Unit
moveBy(delta: Offset, delayMillis: Long)

Sends a move event delayMillis after the last sent event on the associated node, with the position of the default pointer moved by the given delta.

Cmn
open Unit
moveBy(pointerId: Int, delta: Offset, delayMillis: Long)

Sends a move event delayMillis after the last sent event on the associated node, with the position of the pointer with the given pointerId moved by the given delta.

Cmn
open Unit
moveTo(position: Offset, delayMillis: Long)

Sends a move event delayMillis after the last sent event on the associated node, with the position of the default pointer updated to position.

Cmn
open Unit
moveTo(pointerId: Int, position: Offset, delayMillis: Long)

Sends a move event delayMillis after the last sent event on the associated node, with the position of the pointer with the given pointerId updated to position.

Cmn
open Unit
@ExperimentalTestApi
moveWithHistory(
    relativeHistoricalTimes: List<Long>,
    historicalCoordinates: List<Offset>,
    delayMillis: Long
)

Sends a move event delayMillis after the last sent event without updating any of the pointer positions, while adding the historicalCoordinates at the relativeHistoricalTimes to the move event.

Cmn
Unit
@ExperimentalTestApi
moveWithHistoryMultiPointer(
    relativeHistoricalTimes: List<Long>,
    historicalCoordinates: List<List<Offset>>,
    delayMillis: Long
)

Sends a move event delayMillis after the last sent event without updating any of the pointer positions, while adding the historicalCoordinates at the relativeHistoricalTimes to the move event.

Cmn
Unit
up(pointerId: Int)

Sends an up event for the pointer with the given pointerId, or the default pointer if pointerId is omitted, on the associated node.

Cmn
open Unit
updatePointerBy(pointerId: Int, delta: Offset)

Updates the position of the pointer with the given pointerId by the given delta, but does not send a move event.

Cmn
Unit
updatePointerTo(pointerId: Int, position: Offset)

Updates the position of the pointer with the given pointerId to the given position, but does not send a move event.

Cmn

Extension functions

Unit

Performs a click gesture (aka a tap) on the associated node.

Cmn
Unit
TouchInjectionScope.doubleClick(position: Offset, delayMillis: Long)

Performs a double click gesture (aka a double tap) on the associated node.

Cmn
Unit
TouchInjectionScope.longClick(position: Offset, durationMillis: Long)

Performs a long click gesture (aka a long press) on the associated node.

Cmn
Unit
TouchInjectionScope.multiTouchSwipe(
    curves: List<(timeMillis: Long) -> Offset>,
    durationMillis: Long,
    keyTimes: List<Long>
)

Performs a multi touch swipe gesture on the associated node.

Cmn
Unit
TouchInjectionScope.pinch(
    start0: Offset,
    end0: Offset,
    start1: Offset,
    end1: Offset,
    durationMillis: Long
)

Performs a pinch gesture on the associated node.

Cmn
Unit
TouchInjectionScope.swipe(
    curve: (timeMillis: Long) -> Offset,
    durationMillis: Long,
    keyTimes: List<Long>
)

Performs a swipe gesture on the associated node.

Cmn
Unit
TouchInjectionScope.swipe(
    start: Offset,
    end: Offset,
    durationMillis: Long
)

Performs a swipe gesture on the associated node.

Cmn
Unit
TouchInjectionScope.swipeDown(
    startY: Float,
    endY: Float,
    durationMillis: Long
)

Performs a swipe down gesture along x = [centerX] of the associated node, from startY till endY, taking durationMillis milliseconds.

Cmn
Unit
TouchInjectionScope.swipeLeft(
    startX: Float,
    endX: Float,
    durationMillis: Long
)

Performs a swipe left gesture along y = [centerY] of the associated node, from startX till endX, taking durationMillis milliseconds.

Cmn
Unit
TouchInjectionScope.swipeRight(
    startX: Float,
    endX: Float,
    durationMillis: Long
)

Performs a swipe right gesture along y = [centerY] of the associated node, from startX till endX, taking durationMillis milliseconds.

Cmn
Unit
TouchInjectionScope.swipeUp(
    startY: Float,
    endY: Float,
    durationMillis: Long
)

Performs a swipe up gesture along x = [centerX] of the associated node, from startY till endY, taking durationMillis milliseconds.

Cmn
Unit
TouchInjectionScope.swipeWithVelocity(
    start: Offset,
    end: Offset,
    endVelocity: Float,
    durationMillis: Long
)

Performs a swipe gesture on the associated node such that it ends with the given endVelocity.

Cmn

Inherited functions

From androidx.compose.ui.unit.Density
open Int

Convert Dp to Int by rounding

Cmn
open Int

Convert Sp to Int by rounding

Cmn
open Dp

Convert an Int pixel value to Dp.

Cmn
open Dp

Convert a Float pixel value to a Dp

Cmn
open DpSize

Convert a Size to a DpSize.

Cmn
open Float

Convert Dp to pixels.

Cmn
open Float

Convert Sp to pixels.

Cmn
open Rect

Convert a DpRect to a Rect.

Cmn
open Size

Convert a DpSize to a Size.

Cmn
open TextUnit

Convert an Int pixel value to Sp.

Cmn
open TextUnit

Convert a Float pixel value to a Sp

Cmn
From androidx.compose.ui.unit.FontScaling
open Dp

Convert Sp to Dp.

Cmn
open TextUnit

Convert Dp to Sp.

Cmn
From androidx.compose.ui.test.InjectionScope
Unit
advanceEventTime(durationMillis: Long)

Adds the given durationMillis to the current event time, delaying the next event by that time.

Cmn
open Offset

Creates an Offset relative to the size of the node we're interacting with.

Cmn

Inherited properties

From androidx.compose.ui.unit.Density
Float

The logical density of the display.

Cmn
From androidx.compose.ui.unit.FontScaling
Float

Current user preference for the scaling factor for fonts.

Cmn
From androidx.compose.ui.test.InjectionScope
open Float

The y-coordinate for the bottom of the node we're interacting with in px, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The center of the bottom edge of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The bottom left corner of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The bottom right corner of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The center of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The center of the left edge of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The center of the right edge of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Float

The x-coordinate for the center of the node we're interacting with in px, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Float

The y-coordinate for the center of the node we're interacting with in px, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Long

The default time between two successive events.

Cmn
open Int

The height of the node in px.

Cmn
open Float

The x-coordinate for the left edge of the node we're interacting with in px, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Float

The x-coordinate for the right edge of the node we're interacting with in px, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Float

The y-coordinate for the bottom of the node we're interacting with in px, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The center of the top edge of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The top left corner of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
open Offset

The top right corner of the node we're interacting with, in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Cmn
ViewConfiguration

The ViewConfiguration in use by the SemanticsNode from the SemanticsNodeInteraction on which the input injection method is called.

Cmn
IntSize

The size of the visible part of the node we're interacting with in px, i.e. its clipped bounds.

Cmn
open Int

The width of the node in px.

Cmn

Public functions

cancel

fun cancel(delayMillis: Long = eventPeriodMillis): Unit

Sends a cancel event delayMillis after the last sent event to cancel the current gesture. The cancel event contains the current position of all active pointers.

Parameters
delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

currentPosition

fun currentPosition(pointerId: Int = 0): Offset?

Returns the current position of the given pointerId. The default pointerId is 0. The position is returned in the local coordinate system of the node with which we're interacting. (0, 0) is the top left corner of the node.

down

open fun down(position: Offset): Unit

Sends a down event for the default pointer at position on the associated node. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node. The default pointer has pointerId = 0.

If no pointers are down yet, this will start a new touch gesture. If a gesture is already in progress, this event is sent at the same timestamp as the last event. If the default pointer is already down, an IllegalArgumentException will be thrown.

Parameters
position: Offset

The position of the down event, in the node's local coordinate system

down

fun down(pointerId: Int, position: Offset): Unit

Sends a down event for the pointer with the given pointerId at position on the associated node. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node.

If no pointers are down yet, this will start a new touch gesture. If a gesture is already in progress, this event is sent at the same timestamp as the last event. If the given pointer is already down, an IllegalArgumentException will be thrown.

Parameters
pointerId: Int

The id of the pointer, can be any number not yet in use by another pointer

position: Offset

The position of the down event, in the node's local coordinate system

move

fun move(delayMillis: Long = eventPeriodMillis): Unit

Sends a move event delayMillis after the last sent event without updating any of the pointer positions. This can be useful when batching movement of multiple pointers together, which can be done with updatePointerTo and updatePointerBy.

Parameters
delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

moveBy

open fun moveBy(delta: Offset, delayMillis: Long = eventPeriodMillis): Unit

Sends a move event delayMillis after the last sent event on the associated node, with the position of the default pointer moved by the given delta. The default pointer has pointerId = 0.

If the pointer is not yet down, an IllegalArgumentException will be thrown.

Parameters
delta: Offset

The position for this move event, relative to the current position of the pointer. For example, `delta = Offset(10.px, -10.px) will add 10.px to the pointer's x-position, and subtract 10.px from the pointer's y-position.

delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

moveBy

open fun moveBy(pointerId: Int, delta: Offset, delayMillis: Long = eventPeriodMillis): Unit

Sends a move event delayMillis after the last sent event on the associated node, with the position of the pointer with the given pointerId moved by the given delta.

If the pointer is not yet down, an IllegalArgumentException will be thrown.

Parameters
pointerId: Int

The id of the pointer to move, as supplied in down

delta: Offset

The position for this move event, relative to the current position of the pointer. For example, `delta = Offset(10.px, -10.px) will add 10.px to the pointer's x-position, and subtract 10.px from the pointer's y-position.

delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

moveTo

open fun moveTo(position: Offset, delayMillis: Long = eventPeriodMillis): Unit

Sends a move event delayMillis after the last sent event on the associated node, with the position of the default pointer updated to position. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node. The default pointer has pointerId = 0.

If the default pointer is not yet down, an IllegalArgumentException will be thrown.

Parameters
position: Offset

The new position of the pointer, in the node's local coordinate system

delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

moveTo

open fun moveTo(
    pointerId: Int,
    position: Offset,
    delayMillis: Long = eventPeriodMillis
): Unit

Sends a move event delayMillis after the last sent event on the associated node, with the position of the pointer with the given pointerId updated to position. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node.

If the pointer is not yet down, an IllegalArgumentException will be thrown.

Parameters
pointerId: Int

The id of the pointer to move, as supplied in down

position: Offset

The new position of the pointer, in the node's local coordinate system

delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

moveWithHistory

@ExperimentalTestApi
open fun moveWithHistory(
    relativeHistoricalTimes: List<Long>,
    historicalCoordinates: List<Offset>,
    delayMillis: Long = eventPeriodMillis
): Unit

Sends a move event delayMillis after the last sent event without updating any of the pointer positions, while adding the historicalCoordinates at the relativeHistoricalTimes to the move event. This corresponds to the scenario where a touch screen generates touch events quicker than can be dispatched and batches them together.

This overload is a convenience method for the common case where the gesture only has one pointer.

Parameters
relativeHistoricalTimes: List<Long>

Time of each historical event, as a millisecond relative to the time the actual event is sent. For example, -10L means 10ms earlier.

historicalCoordinates: List<Offset>

Coordinates of each historical event, in the same coordinate space as moveTo. The list must have the same size as relativeHistoricalTimes.

delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

moveWithHistoryMultiPointer

@ExperimentalTestApi
fun moveWithHistoryMultiPointer(
    relativeHistoricalTimes: List<Long>,
    historicalCoordinates: List<List<Offset>>,
    delayMillis: Long = eventPeriodMillis
): Unit

Sends a move event delayMillis after the last sent event without updating any of the pointer positions, while adding the historicalCoordinates at the relativeHistoricalTimes to the move event. This corresponds to the scenario where a touch screen generates touch events quicker than can be dispatched and batches them together.

import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.performTouchInput

// Move two fingers in a horizontal line, one on y=100 and one on y=500
composeTestRule.onNodeWithTag("myComponent").performTouchInput {
    // First, make contact with the screen with both pointers:
    down(0, Offset(300f, 100f))
    down(1, Offset(300f, 500f))
    // Update the pointer locations for the next event
    updatePointerTo(0, Offset(400f, 100f))
    updatePointerTo(1, Offset(400f, 500f))
    // And send the move event with historical data
    @OptIn(ExperimentalTestApi::class)
    moveWithHistoryMultiPointer(
        // Let's add 3 historical events
        relativeHistoricalTimes = listOf(-12, -8, -4),
        // Now, for each pointer we supply the historical coordinates
        historicalCoordinates =
            listOf(
                // Pointer 0 moves along y=100
                listOf(Offset(325f, 100f), Offset(350f, 100f), Offset(375f, 100f)),
                // Pointer 1 moves along y=500
                listOf(Offset(325f, 500f), Offset(350f, 500f), Offset(375f, 500f)),
            ),
        // The actual move event will be sent 16ms after the previous event
        delayMillis = 16
    )
    // And finish the gesture by lifting both fingers. Can be done in any order
    up(1)
    up(0)
}
Parameters
relativeHistoricalTimes: List<Long>

Time of each historical event, as a millisecond relative to the time the actual event is sent. For example, -10L means 10ms earlier.

historicalCoordinates: List<List<Offset>>

Coordinates of each historical event, in the same coordinate space as moveTo. The outer list must have the same size as the number of pointers in the event, and each inner list must have the same size as relativeHistoricalTimes. The ith pointer is assigned the ith history, with the pointers sorted on ascending pointerId.

delayMillis: Long = eventPeriodMillis

The time between the last sent event and this event. eventPeriodMillis by default.

up

fun up(pointerId: Int = 0): Unit

Sends an up event for the pointer with the given pointerId, or the default pointer if pointerId is omitted, on the associated node.

Parameters
pointerId: Int = 0

The id of the pointer to lift up, as supplied in down

updatePointerBy

open fun updatePointerBy(pointerId: Int, delta: Offset): Unit

Updates the position of the pointer with the given pointerId by the given delta, but does not send a move event. The move event can be sent with move.

If the pointer is not yet down, an IllegalArgumentException will be thrown.

Parameters
pointerId: Int

The id of the pointer to move, as supplied in down

delta: Offset

The position for this move event, relative to the last sent position of the pointer. For example, `delta = Offset(10.px, -10.px) will add 10.px to the pointer's x-position, and subtract 10.px from the pointer's y-position.

updatePointerTo

fun updatePointerTo(pointerId: Int, position: Offset): Unit

Updates the position of the pointer with the given pointerId to the given position, but does not send a move event. The move event can be sent with move. The position is in the node's local coordinate system, where (0.px, 0.px) is the top left corner of the node.

If the pointer is not yet down, an IllegalArgumentException will be thrown.

Parameters
pointerId: Int

The id of the pointer to move, as supplied in down

position: Offset

The new position of the pointer, in the node's local coordinate system

Extension functions

fun TouchInjectionScope.click(position: Offset = center): Unit

Performs a click gesture (aka a tap) on the associated node.

The click is done at the given position, or in the center if the position is omitted. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Parameters
position: Offset = center

The position where to click, in the node's local coordinate system. If omitted, the center of the node will be used.

doubleClick

fun TouchInjectionScope.doubleClick(
    position: Offset = center,
    delayMillis: Long = viewConfiguration.defaultDoubleTapDelayMillis
): Unit

Performs a double click gesture (aka a double tap) on the associated node.

The double click is done at the given position or in the center if the position is omitted. By default, the delayMillis between the first and the second click is half way in between the minimum and maximum required delay for a double click. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Parameters
position: Offset = center

The position of the double click, in the node's local coordinate system. If omitted, the center position will be used.

delayMillis: Long = viewConfiguration.defaultDoubleTapDelayMillis

The time between the up event of the first click and the down event of the second click

longClick

fun TouchInjectionScope.longClick(
    position: Offset = center,
    durationMillis: Long = viewConfiguration.longPressTimeoutMillis + 100
): Unit

Performs a long click gesture (aka a long press) on the associated node.

The long click is done at the given position, or in the center if the position is omitted. By default, the durationMillis of the press is 100ms longer than the minimum required duration for a long press. The position is in the node's local coordinate system, where (0, 0) is the top left corner of the node.

Parameters
position: Offset = center

The position of the long click, in the node's local coordinate system. If omitted, the center of the node will be used.

durationMillis: Long = viewConfiguration.longPressTimeoutMillis + 100

The time between the down and the up event

multiTouchSwipe

fun TouchInjectionScope.multiTouchSwipe(
    curves: List<(timeMillis: Long) -> Offset>,
    durationMillis: Long = 200,
    keyTimes: List<Long> = emptyList()
): Unit

Performs a multi touch swipe gesture on the associated node.

Each pointer follows curves[i] from 0 till durationMillis. Sampling of an event is forced at all times defined in keyTimes. The time between events is kept as close to eventPeriodMillis as possible, given the constraints. The coordinates are in the node's local coordinate system, where (0, 0) is the top left corner of the node. The default duration is 200 milliseconds.

Parameters
curves: List<(timeMillis: Long) -> Offset>

The functions that describe the gesture. Function i defines the position over time for pointer id i. The argument passed to each function is the time in milliseconds since the start of the swipe, and the return value is the location of that pointer at that point in time.

durationMillis: Long = 200

The duration of the gesture

keyTimes: List<Long> = emptyList()

An optional list of timestamps in milliseconds at which a move event must be sampled

fun TouchInjectionScope.pinch(
    start0: Offset,
    end0: Offset,
    start1: Offset,
    end1: Offset,
    durationMillis: Long = 400
): Unit

Performs a pinch gesture on the associated node.

For each pair of start and end Offsets, the motion events are linearly interpolated. The coordinates are in the node's local coordinate system where (0, 0) is the top left corner of the node. The default duration is 400 milliseconds.

Parameters
start0: Offset

The start position of the first gesture in the node's local coordinate system

end0: Offset

The end position of the first gesture in the node's local coordinate system

start1: Offset

The start position of the second gesture in the node's local coordinate system

end1: Offset

The end position of the second gesture in the node's local coordinate system

durationMillis: Long = 400

the duration of the gesture

fun TouchInjectionScope.swipe(
    curve: (timeMillis: Long) -> Offset,
    durationMillis: Long = 200,
    keyTimes: List<Long> = emptyList()
): Unit

Performs a swipe gesture on the associated node.

The swipe follows the curve from 0 till durationMillis. Will force sampling of an event at all times defined in keyTimes. The time between events is kept as close to eventPeriodMillis as possible, given the constraints. The coordinates are in the node's local coordinate system, where (0, 0) is the top left corner of the node. The default duration is 200 milliseconds.

Parameters
curve: (timeMillis: Long) -> Offset

The function that describes the gesture. The argument passed to the function is the time in milliseconds since the start of the swipe, and the return value is the location of the pointer at that point in time.

durationMillis: Long = 200

The duration of the gesture

keyTimes: List<Long> = emptyList()

An optional list of timestamps in milliseconds at which a move event must be sampled

fun TouchInjectionScope.swipe(
    start: Offset,
    end: Offset,
    durationMillis: Long = 200
): Unit

Performs a swipe gesture on the associated node.

The motion events are linearly interpolated between start and end. The coordinates are in the node's local coordinate system, where (0, 0) is the top left corner of the node. The default duration is 200 milliseconds.

Parameters
start: Offset

The start position of the gesture, in the node's local coordinate system

end: Offset

The end position of the gesture, in the node's local coordinate system

durationMillis: Long = 200

The duration of the gesture

swipeDown

fun TouchInjectionScope.swipeDown(
    startY: Float = top,
    endY: Float = bottom,
    durationMillis: Long = 200
): Unit

Performs a swipe down gesture along x = [centerX] of the associated node, from startY till endY, taking durationMillis milliseconds.

Parameters
startY: Float = top

The y-coordinate of the start of the swipe. Must be less than or equal to the endY. By default the top of the node.

endY: Float = bottom

The y-coordinate of the end of the swipe. Must be greater than or equal to the startY. By default the bottom of the node.

durationMillis: Long = 200

The duration of the swipe. By default 200 milliseconds.

swipeLeft

fun TouchInjectionScope.swipeLeft(
    startX: Float = right,
    endX: Float = left,
    durationMillis: Long = 200
): Unit

Performs a swipe left gesture along y = [centerY] of the associated node, from startX till endX, taking durationMillis milliseconds.

Parameters
startX: Float = right

The x-coordinate of the start of the swipe. Must be greater than or equal to the endX. By default the right of the node.

endX: Float = left

The x-coordinate of the end of the swipe. Must be less than or equal to the startX. By default the left of the node.

durationMillis: Long = 200

The duration of the swipe. By default 200 milliseconds.

swipeRight

fun TouchInjectionScope.swipeRight(
    startX: Float = left,
    endX: Float = right,
    durationMillis: Long = 200
): Unit

Performs a swipe right gesture along y = [centerY] of the associated node, from startX till endX, taking durationMillis milliseconds.

Parameters
startX: Float = left

The x-coordinate of the start of the swipe. Must be less than or equal to the endX. By default the left of the node.

endX: Float = right

The x-coordinate of the end of the swipe. Must be greater than or equal to the startX. By default the right of the node.

durationMillis: Long = 200

The duration of the swipe. By default 200 milliseconds.

fun TouchInjectionScope.swipeUp(
    startY: Float = bottom,
    endY: Float = top,
    durationMillis: Long = 200
): Unit

Performs a swipe up gesture along x = [centerX] of the associated node, from startY till endY, taking durationMillis milliseconds.

Parameters
startY: Float = bottom

The y-coordinate of the start of the swipe. Must be greater than or equal to the endY. By default the bottom of the node.

endY: Float = top

The y-coordinate of the end of the swipe. Must be less than or equal to the startY. By default the top of the node.

durationMillis: Long = 200

The duration of the swipe. By default 200 milliseconds.

swipeWithVelocity

fun TouchInjectionScope.swipeWithVelocity(
    start: Offset,
    end: Offset,
    endVelocity: Float,
    durationMillis: Long = VelocityPathFinder.calculateDefaultDuration(start, end, endVelocity)
): Unit

Performs a swipe gesture on the associated node such that it ends with the given endVelocity.

The swipe will go through start at t=0 and through end at t=durationMillis. In between, the swipe will go monotonically from start and end, but not strictly. Due to imprecision, no guarantees can be made for the actual velocity at the end of the gesture, but generally it is within 0.1 of the desired velocity.

When a swipe cannot be created that results in the desired velocity (because the input is too restrictive), an exception will be thrown with suggestions to fix the input.

The coordinates are in the node's local coordinate system, where (0, 0) is the top left corner of the node. The default duration is calculated such that a feasible swipe can be created that ends in the given velocity.

Parameters
start: Offset

The start position of the gesture, in the node's local coordinate system

end: Offset

The end position of the gesture, in the node's local coordinate system

endVelocity: Float

The velocity of the gesture at the moment it ends in px/second. Must be positive.

durationMillis: Long = VelocityPathFinder.calculateDefaultDuration(start, end, endVelocity)

The duration of the gesture in milliseconds. Must be long enough that at least 3 input events are generated, which happens with a duration of 40ms or more. If omitted, a duration is calculated such that a valid swipe with velocity can be created.

Throws
kotlin.IllegalArgumentException

When no swipe can be generated that will result in the desired velocity. The error message will suggest changes to the input parameters such that a swipe will become feasible.