SwipeToDismissBox.kt
/*
* Copyright 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.wear.compose.material3
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.key
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.wear.compose.foundation.LocalSwipeToDismissBackgroundScrimColor
import androidx.wear.compose.foundation.LocalSwipeToDismissContentScrimColor
import androidx.wear.compose.foundation.SwipeToDismissBoxState
import androidx.wear.compose.foundation.SwipeToDismissKeys
import androidx.wear.compose.foundation.edgeSwipeToDismiss
import androidx.wear.compose.foundation.rememberSwipeToDismissBoxState
/**
* Wear Material 3 [SwipeToDismissBox] that handles the swipe-to-dismiss gesture. Takes a single
* slot for the background (only displayed during the swipe gesture) and the foreground content.
*
* Example of a [SwipeToDismissBox] with stateful composables:
* @sample androidx.wear.compose.material3.samples.StatefulSwipeToDismissBox
*
* Example of using [Modifier.edgeSwipeToDismiss] with [SwipeToDismissBox]:
* @sample androidx.wear.compose.material3.samples.EdgeSwipeForSwipeToDismiss
*
* For more information, see the
* [Swipe to dismiss](https://developer.android.com/training/wearables/components/swipe-to-dismiss)
* guide.
*
* @param state State containing information about ongoing swipe or animation.
* @param modifier [Modifier] for this component.
* @param backgroundScrimColor [Color] for background scrim.
* @param contentScrimColor [Color] used for the scrim over the content composable during
* the swipe gesture.
* @param backgroundKey [key] which identifies the content currently composed in
* the [content] block when isBackground == true. Provide the backgroundKey if your background
* content will be displayed as a foreground after the swipe animation ends
* (as is common when [SwipeToDismissBox] is used for the navigation). This allows
* remembered state to be correctly moved between background and foreground.
* @param contentKey [key] which identifies the content currently composed in the
* [content] block when isBackground == false. See [backgroundKey].
* @param userSwipeEnabled Whether the swipe gesture is enabled.
* (e.g. when there is no background screen, set userSwipeEnabled = false)
* @param content Slot for content, with the isBackground parameter enabling content to be
* displayed behind the foreground content - the background is normally hidden, is shown behind a
* scrim during the swipe gesture, and is shown without scrim once the finger passes the
* swipe-to-dismiss threshold.
*/
@Composable
fun SwipeToDismissBox(
state: SwipeToDismissBoxState,
modifier: Modifier = Modifier,
backgroundScrimColor: Color = MaterialTheme.colorScheme.background,
contentScrimColor: Color = MaterialTheme.colorScheme.background,
backgroundKey: Any = SwipeToDismissKeys.Background,
contentKey: Any = SwipeToDismissKeys.Content,
userSwipeEnabled: Boolean = true,
content: @Composable BoxScope.(isBackground: Boolean) -> Unit
) {
CompositionLocalProvider(
LocalSwipeToDismissBackgroundScrimColor provides backgroundScrimColor,
LocalSwipeToDismissContentScrimColor provides contentScrimColor
) {
androidx.wear.compose.foundation.BasicSwipeToDismissBox(
state = state,
modifier = modifier,
backgroundKey = backgroundKey,
contentKey = contentKey,
userSwipeEnabled = userSwipeEnabled,
content = content
)
}
}
/**
* Wear Material 3 [SwipeToDismissBox] that handles the swipe-to-dismiss gesture.
* This overload takes an [onDismissed] parameter which is used to execute a command when the
* swipe to dismiss has completed, such as navigating to another screen.
*
* Example of a simple SwipeToDismissBox:
* @sample androidx.wear.compose.material3.samples.SimpleSwipeToDismissBox
*
* Example of using [Modifier.edgeSwipeToDismiss] with [SwipeToDismissBox]:
* @sample androidx.wear.compose.material3.samples.EdgeSwipeForSwipeToDismiss
*
* For more information, see the
* [Swipe to dismiss](https://developer.android.com/training/wearables/components/swipe-to-dismiss)
* guide.
*
* @param onDismissed Executes when the swipe to dismiss has completed.
* @param modifier [Modifier] for this component.
* @param state State containing information about ongoing swipe or animation.
* @param backgroundScrimColor [Color] for background scrim.
* @param contentScrimColor [Color] used for the scrim over the content composable during
* the swipe gesture.
* @param backgroundKey [key] which identifies the content currently composed in
* the [content] block when isBackground == true. Provide the backgroundKey if your background
* content will be displayed as a foreground after the swipe animation ends
* (as is common when [SwipeToDismissBox] is used for the navigation). This allows
* remembered state to be correctly moved between background and foreground.
* @param contentKey [key] which identifies the content currently composed in the
* [content] block when isBackground == false. See [backgroundKey].
* @param userSwipeEnabled Whether the swipe gesture is enabled.
* (e.g. when there is no background screen, set userSwipeEnabled = false)
* @param content Slot for content, with the isBackground parameter enabling content to be
* displayed behind the foreground content - the background is normally hidden, is shown behind a
* scrim during the swipe gesture, and is shown without scrim once the finger passes the
* swipe-to-dismiss threshold.
*/
@Composable
fun SwipeToDismissBox(
onDismissed: () -> Unit,
modifier: Modifier = Modifier,
state: SwipeToDismissBoxState = rememberSwipeToDismissBoxState(),
backgroundScrimColor: Color = MaterialTheme.colorScheme.background,
contentScrimColor: Color = MaterialTheme.colorScheme.background,
backgroundKey: Any = SwipeToDismissKeys.Background,
contentKey: Any = SwipeToDismissKeys.Content,
userSwipeEnabled: Boolean = true,
content: @Composable BoxScope.(isBackground: Boolean) -> Unit
) {
CompositionLocalProvider(
LocalSwipeToDismissBackgroundScrimColor provides backgroundScrimColor,
LocalSwipeToDismissContentScrimColor provides contentScrimColor
) {
androidx.wear.compose.foundation.BasicSwipeToDismissBox(
state = state,
modifier = modifier,
onDismissed = onDismissed,
backgroundKey = backgroundKey,
contentKey = contentKey,
userSwipeEnabled = userSwipeEnabled,
content = content
)
}
}