androidx.ui.foundation.gestures

Classes

DragDirection

Draggable Direction specifies the direction in which you can drag an Draggable.

FloatDragValueController

Simple DragValueController that backs up single Float value with no fling support

ScrollableState

State of the Scrollable composable.

Top-level functions summary

Unit
Draggable(dragDirection: DragDirection, dragValue: AnimatedFloat, onDragValueChangeRequested: (Float) -> Unit, onDragStarted: (startedPosition: PxPosition) -> Unit = {}, onDragStopped: (velocity: Float) -> Unit = {}, enabled: Boolean = true, isValueAnimating: Boolean = false, children: () -> Unit)

Component that provides high-level drag functionality reflected in one value

Unit
Scrollable(dragDirection: DragDirection, scrollableState: ScrollableState, onScrollStarted: (startedPosition: PxPosition) -> Unit = {}, onScrollStopped: (velocity: Float) -> Unit = {}, enabled: Boolean = true, children: () -> Unit)

Component that provides high-level scroll functionality

ScrollableState
ScrollableState(onScrollDeltaConsumptionRequested: (Float) -> Float)

Create ScrollableState for Scrollable with default FlingConfig and AnimationClockObservable

Top-level functions

Draggable

@Composable fun Draggable(
    dragDirection: DragDirection,
    dragValue: AnimatedFloat,
    onDragValueChangeRequested: (Float) -> Unit,
    onDragStarted: (startedPosition: PxPosition) -> Unit = {},
    onDragStopped: (velocity: Float) -> Unit = {},
    enabled: Boolean = true,
    isValueAnimating: Boolean = false,
    children: () -> Unit
): Unit

Component that provides high-level drag functionality reflected in one value

The common usecase for this component is when you need to be able to drag/scroll something on the screen and represent it as one value via AnimatedFloat.

If you need to control the whole dragging flow, consider using TouchSlopDragGestureDetector instead.

import androidx.ui.animation.animatedFloat
import androidx.ui.foundation.ColoredRect
import androidx.ui.foundation.gestures.Draggable
import androidx.ui.foundation.shape.DrawShape
import androidx.ui.layout.Container
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.LayoutSize

val max = 300.dp
val min = 0.dp
val (minPx, maxPx) = with(DensityAmbient.current) {
    min.toPx().value to max.toPx().value
}
val position = animatedFloat(0f)
position.setBounds(minPx, maxPx)
Draggable(
    dragValue = position,
    onDragValueChangeRequested = { position.snapTo(it) },
    dragDirection = DragDirection.Horizontal
) {
    // dragValue is the current value in progress of dragging
    val draggedDp = with(DensityAmbient.current) {
        position.value.toDp()
    }
    val squareSize = 50.dp

    // Draw a seekbar-like composable that has a black background
    // with a red square that moves along the drag
    Container(width = max + squareSize, alignment = Alignment.CenterLeft) {
        DrawShape(RectangleShape, Color.Black)
        ColoredRect(
            Color.Red,
            LayoutPadding(left = draggedDp) + LayoutSize(squareSize, squareSize)
        )
    }
}
By using AnimatedFloat as dragValue you can achievefling behaviour by calling fling on it
import androidx.ui.animation.animatedFloat
import androidx.ui.foundation.ColoredRect
import androidx.ui.foundation.animation.AnchorsFlingConfig
import androidx.ui.foundation.animation.fling
import androidx.ui.foundation.gestures.Draggable
import androidx.ui.foundation.shape.DrawShape
import androidx.ui.layout.Container
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.LayoutSize

val max = 300.dp
val min = 0.dp
val (minPx, maxPx) = with(DensityAmbient.current) {
    min.toPx().value to max.toPx().value
}
// define anchors and related animation controller
val anchors = listOf(minPx, maxPx, maxPx / 2)
val flingConfig = AnchorsFlingConfig(anchors)
val position = animatedFloat(0f)
position.setBounds(minPx, maxPx)

Draggable(
    dragValue = position,
    onDragValueChangeRequested = { position.snapTo(it) },
    dragDirection = DragDirection.Horizontal,
    onDragStopped = { position.fling(flingConfig, it) }
) {
    val draggedDp = with(DensityAmbient.current) { position.value.toDp() }
    val squareSize = 50.dp

    // Draw a seekbar-like widget that has a black background
    // with a red square that moves along the drag
    Container(width = max + squareSize, alignment = Alignment.CenterLeft) {
        DrawShape(RectangleShape, Color.Black)
        ColoredRect(
            Color.Red,
            LayoutPadding(left = draggedDp) + LayoutSize(squareSize, squareSize)
        )
    }
}
Parameters
dragDirection: DragDirection direction in which drag should be happening
dragValue: AnimatedFloat value holder for value that needs to be dragged
onDragValueChangeRequested: (Float) -> Unit callback to be invoked when drag happened and change on dragValue is requested. The value should be updated synchronously in order to provide smooth dragging experience
onDragStarted: (startedPosition: PxPosition) -> Unit = {} callback that will be invoked when drag has been started after touch slop has been passed, with starting position provided
onDragStopped: (velocity: Float) -> Unit = {} callback that will be invoked when drag stops, with velocity provided
enabled: Boolean = true whether or not drag is enabled
isValueAnimating: Boolean = false Set to true when dragValue is being animated. Setting to true will inform this Draggable that it should start dragging and prevent other gesture detectors from reacting to "down" events (in order to block composed press-based gestures). This is intended to allow end users to "catch" an animating widget by pressing on it.

Scrollable

@Composable fun Scrollable(
    dragDirection: DragDirection,
    scrollableState: ScrollableState,
    onScrollStarted: (startedPosition: PxPosition) -> Unit = {},
    onScrollStopped: (velocity: Float) -> Unit = {},
    enabled: Boolean = true,
    children: () -> Unit
): Unit

Component that provides high-level scroll functionality

When you need something to be able to scroll with fling support and smooth scrolling capabilities, consider using this composable.

Although ScrollableState is required for this composable to be able to work correctly, users of this composable should own, update and reflect their own state. When constructing ScrollableState, you need to pass ScrollableState.onScrollDeltaConsumptionRequested lambda, which will be invoked every time with the delta when scroll is happening (by gesture input, my smooth scrolling or flinging). In this lambda you can change your own state and reflect it on UI. Amount of scrolling delta consumed must be returned from this lambda.

import androidx.compose.state
import androidx.ui.core.Text
import androidx.ui.foundation.Box
import androidx.ui.foundation.gestures.Scrollable
import androidx.ui.foundation.gestures.ScrollableState
import androidx.ui.layout.LayoutSize
import androidx.ui.text.TextStyle

// actual composable state
val offset = state { 0f }
// state for Scrollable, describes how to consume scrolling delta and update offset
val scrollableState = ScrollableState(
    onScrollDeltaConsumptionRequested = { delta ->
        offset.value += delta
        delta
    }
)
Scrollable(dragDirection = DragDirection.Vertical, scrollableState = scrollableState) {
    Box(
        LayoutSize(200.dp),
        backgroundColor = Color.LightGray,
        gravity = ContentGravity.Center
    ) {
        Text(offset.value.roundToInt().toString(), style = TextStyle(fontSize = 50.sp))
    }
}
Parameters
dragDirection: DragDirection axis to scroll alongside
scrollableState: ScrollableState ScrollableState object that holds internal state of this Scrollable, invokes ScrollableState.onScrollDeltaConsumptionRequested callback and provides smooth scrolling capabilities
onScrollStarted: (startedPosition: PxPosition) -> Unit = {} callback to be invoked when scroll has started from the certain position on the screen
onScrollStopped: (velocity: Float) -> Unit = {} callback to be invoked when scroll stops with amount of velocity unconsumed provided
enabled: Boolean = true whether of not scrolling in enabled

ScrollableState

@Composable fun ScrollableState(onScrollDeltaConsumptionRequested: (Float) -> Float): ScrollableState

Create ScrollableState for Scrollable with default FlingConfig and AnimationClockObservable

Parameters
onScrollDeltaConsumptionRequested: (Float) -> Float callback to be invoked when scrollable drag/fling/smooth scrolling occurs. Users must update their state in this lambda and return amount of delta consumed