Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a6043288 authored by Omar Miatello's avatar Omar Miatello Committed by Android (Google) Code Review
Browse files

Merge changes I4cc652fe,I03f43442 into main

* changes:
  PriorityNestedScrollConnection: make onStop suspendable and add onCancel
  Simplify PriorityNestedScrollConnection
parents 079cf667 5a834336
Loading
Loading
Loading
Loading
+16 −12
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.systemui.notifications.ui.composable

import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.util.fastCoerceAtLeast
import androidx.compose.ui.util.fastCoerceAtMost
import com.android.compose.nestedscroll.PriorityNestedScrollConnection

/**
@@ -44,7 +46,7 @@ fun NotificationScrimNestedScrollConnection(
        orientation = Orientation.Vertical,
        // scrolling up and inner content is taller than the scrim, so scrim needs to
        // expand; content can scroll once scrim is at the minScrimOffset.
        canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
        canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
            offsetAvailable < 0 &&
                offsetBeforeStart == 0f &&
                contentHeight() > minVisibleScrimHeight() &&
@@ -52,36 +54,38 @@ fun NotificationScrimNestedScrollConnection(
        },
        // scrolling down and content is done scrolling to top. After that, the scrim
        // needs to collapse; collapse the scrim until it is at the maxScrimOffset.
        canStartPostScroll = { offsetAvailable, _ ->
        canStartPostScroll = { offsetAvailable, _, _ ->
            offsetAvailable > 0 && (scrimOffset() < maxScrimOffset || isCurrentGestureOverscroll())
        },
        canStartPostFling = { false },
        canContinueScroll = {
            val currentHeight = scrimOffset()
            minScrimOffset() < currentHeight && currentHeight < maxScrimOffset
        },
        canScrollOnFling = true,
        canStopOnPreFling = { false },
        onStart = { offsetAvailable -> onStart(offsetAvailable) },
        onScroll = { offsetAvailable ->
        onScroll = { offsetAvailable, _ ->
            val currentHeight = scrimOffset()
            val amountConsumed =
                if (offsetAvailable > 0) {
                    val amountLeft = maxScrimOffset - currentHeight
                    offsetAvailable.coerceAtMost(amountLeft)
                    offsetAvailable.fastCoerceAtMost(amountLeft)
                } else {
                    val amountLeft = minScrimOffset() - currentHeight
                    offsetAvailable.coerceAtLeast(amountLeft)
                    offsetAvailable.fastCoerceAtLeast(amountLeft)
                }
            snapScrimOffset(currentHeight + amountConsumed)
            amountConsumed
        },
        // Don't consume the velocity on pre/post fling
        onStop = { velocityAvailable ->
            onStop(velocityAvailable)
            if (scrimOffset() < minScrimOffset()) {
                animateScrimOffset(minScrimOffset())
            }
            { 0f }
            // Don't consume the velocity on pre/post fling
            0f
        },
        onCancel = {
            onStop(0f)
            if (scrimOffset() < minScrimOffset()) {
                animateScrimOffset(minScrimOffset())
            }
        },
    )
}
+13 −8
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastCoerceAtLeast
import com.android.compose.nestedscroll.PriorityNestedScrollConnection
import kotlin.math.max
import kotlin.math.roundToInt
@@ -86,21 +87,25 @@ fun NotificationStackNestedScrollConnection(
): PriorityNestedScrollConnection {
    return PriorityNestedScrollConnection(
        orientation = Orientation.Vertical,
        canStartPreScroll = { _, _ -> false },
        canStartPostScroll = { offsetAvailable, offsetBeforeStart ->
        canStartPreScroll = { _, _, _ -> false },
        canStartPostScroll = { offsetAvailable, offsetBeforeStart, _ ->
            offsetAvailable < 0f && offsetBeforeStart < 0f && !canScrollForward()
        },
        canStartPostFling = { velocityAvailable -> velocityAvailable < 0f && !canScrollForward() },
        canContinueScroll = { stackOffset() > 0f },
        canScrollOnFling = true,
        canStopOnPreFling = { false },
        onStart = { offsetAvailable -> onStart(offsetAvailable) },
        onScroll = { offsetAvailable ->
            onScroll(offsetAvailable)
            offsetAvailable
        onScroll = { offsetAvailable, _ ->
            val minOffset = 0f
            val consumed = offsetAvailable.fastCoerceAtLeast(minOffset - stackOffset())
            if (consumed != 0f) {
                onScroll(consumed)
            }
            consumed
        },
        onStop = { velocityAvailable ->
            onStop(velocityAvailable)
            suspend { velocityAvailable }
            velocityAvailable
        },
        onCancel = { onStop(0f) },
    )
}
+18 −10
Original line number Diff line number Diff line
@@ -27,9 +27,10 @@ import com.android.compose.animation.scene.content.Content
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
import com.android.compose.nestedscroll.PriorityNestedScrollConnection
import com.android.compose.nestedscroll.SuspendedValue
import kotlin.math.absoluteValue

internal typealias SuspendedValue<T> = suspend () -> T

internal interface DraggableHandler {
    /**
     * Start a drag in the given [startedPosition], with the given [overSlop] and number of
@@ -612,7 +613,7 @@ internal class NestedScrollHandlerImpl(

        return PriorityNestedScrollConnection(
            orientation = orientation,
            canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
            canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
                canChangeScene =
                    if (isExternalOverscrollGesture()) false else offsetBeforeStart == 0f

@@ -638,7 +639,7 @@ internal class NestedScrollHandlerImpl(
                isIntercepting = true
                true
            },
            canStartPostScroll = { offsetAvailable, offsetBeforeStart ->
            canStartPostScroll = { offsetAvailable, offsetBeforeStart, _ ->
                val behavior: NestedScrollBehavior =
                    when {
                        offsetAvailable > 0f -> topOrLeftBehavior
@@ -693,8 +694,7 @@ internal class NestedScrollHandlerImpl(

                canStart
            },
            canContinueScroll = { true },
            canScrollOnFling = false,
            canStopOnPreFling = { true },
            onStart = { offsetAvailable ->
                val pointersInfo = pointersInfo()
                dragController =
@@ -704,7 +704,7 @@ internal class NestedScrollHandlerImpl(
                        overSlop = if (isIntercepting) 0f else offsetAvailable,
                    )
            },
            onScroll = { offsetAvailable ->
            onScroll = { offsetAvailable, _ ->
                val controller = dragController ?: error("Should be called after onStart")

                // TODO(b/297842071) We should handle the overscroll or slow drag if the gesture is
@@ -713,10 +713,18 @@ internal class NestedScrollHandlerImpl(
            },
            onStop = { velocityAvailable ->
                val controller = dragController ?: error("Should be called after onStart")

                try {
                    controller
                        .onStop(velocity = velocityAvailable, canChangeContent = canChangeScene)
                    .also { dragController = null }
                        .invoke()
                } finally {
                    dragController = null
                }
            },
            onCancel = {
                val controller = dragController ?: error("Should be called after onStart")
                controller.onStop(velocity = 0f, canChangeContent = canChangeScene)
                dragController = null
            },
        )
    }
+0 −1
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.unit.IntSize
import com.android.compose.animation.scene.content.state.TransitionState
import com.android.compose.animation.scene.content.state.TransitionState.HasOverscrollProperties.Companion.DistanceUnspecified
import com.android.compose.nestedscroll.SuspendedValue
import kotlin.math.absoluteValue
import kotlinx.coroutines.CompletableDeferred

+10 −11
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.compose.nestedscroll

import androidx.compose.foundation.gestures.Orientation
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
import androidx.compose.ui.util.fastCoerceAtLeast
import androidx.compose.ui.util.fastCoerceAtMost

/**
 * A [NestedScrollConnection] that listens for all vertical scroll events and responds in the
@@ -43,35 +45,32 @@ fun LargeTopAppBarNestedScrollConnection(
        orientation = Orientation.Vertical,
        // When swiping up, the LargeTopAppBar will shrink (to [minHeight]) and the content will
        // expand. Then, you can then scroll down the content.
        canStartPreScroll = { offsetAvailable, offsetBeforeStart ->
        canStartPreScroll = { offsetAvailable, offsetBeforeStart, _ ->
            offsetAvailable < 0 && offsetBeforeStart == 0f && height() > minHeight()
        },
        // When swiping down, the content will scroll up until it reaches the top. Then, the
        // LargeTopAppBar will expand until it reaches its [maxHeight].
        canStartPostScroll = { offsetAvailable, _ ->
        canStartPostScroll = { offsetAvailable, _, _ ->
            offsetAvailable > 0 && height() < maxHeight()
        },
        canStartPostFling = { false },
        canContinueScroll = {
            val currentHeight = height()
            minHeight() < currentHeight && currentHeight < maxHeight()
        },
        canScrollOnFling = true,
        canStopOnPreFling = { false },
        onStart = { /* do nothing */ },
        onScroll = { offsetAvailable ->
        onScroll = { offsetAvailable, _ ->
            val currentHeight = height()
            val amountConsumed =
                if (offsetAvailable > 0) {
                    val amountLeft = maxHeight() - currentHeight
                    offsetAvailable.coerceAtMost(amountLeft)
                    offsetAvailable.fastCoerceAtMost(amountLeft)
                } else {
                    val amountLeft = minHeight() - currentHeight
                    offsetAvailable.coerceAtLeast(amountLeft)
                    offsetAvailable.fastCoerceAtLeast(amountLeft)
                }
            onHeightChanged(currentHeight + amountConsumed)
            amountConsumed
        },
        // Don't consume the velocity on pre/post fling
        onStop = { { 0f } },
        onStop = { 0f },
        onCancel = { /* do nothing */ },
    )
}
Loading