Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package com.example.compose.snippets.predictiveback

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController
import androidx.navigation.NavHostController
import androidx.compose.animation.scaleOut
import androidx.compose.ui.graphics.TransformOrigin
import androidx.compose.animation.EnterTransition
import android.os.SystemClock
import androidx.activity.compose.PredictiveBackHandler
import androidx.compose.ui.unit.dp
import androidx.compose.animation.core.Animatable
import androidx.navigation.compose.composable
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Surface
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.input.pointer.util.VelocityTracker
import androidx.compose.ui.platform.LocalDensity
import kotlin.coroutines.cancellation.CancellationException


@Composable
private fun PredictiveBackOverrideExit(
modifier: Modifier,
) {
val navController = rememberNavController()

// [START android_compose_predictiveback_navhost]
NavHost(
navController = navController,
startDestination = "home",
popExitTransition = {
scaleOut(
targetScale = 0.9f,
transformOrigin = TransformOrigin(pivotFractionX = 0.5f, pivotFractionY = 0.5f)
)
},
popEnterTransition = {
EnterTransition.None
},
modifier = modifier,
)
// [END android_compose_predictiveback_navhost]
{
composable("home") {
HomeScreen(
modifier = modifier,
navController = navController,
)
}
composable("settings") {
SettingsScreen(
modifier = modifier,
navController = navController,
)
}
}
}

@Composable
private fun HomeScreen(
modifier: Modifier = Modifier, navController: NavHostController
) {

}

@Composable
private fun SettingsScreen(
modifier: Modifier = Modifier, navController: NavHostController
) {

}

@Composable
private fun PredictiveBackHandlerManualProgress() {

Surface(
modifier = Modifier.fillMaxSize()
) {
var drawerState by remember {
mutableStateOf(DrawerState.Closed)
}

val translationX = remember {
Animatable(0f)
}

val drawerWidth = with(LocalDensity.current) {
DrawerWidth.toPx()
}
translationX.updateBounds(0f, drawerWidth)

val coroutineScope = rememberCoroutineScope()

suspend fun closeDrawer(velocity: Float = 0f) {
translationX.animateTo(targetValue = 0f, initialVelocity = velocity)
drawerState = DrawerState.Closed
}
suspend fun openDrawer(velocity: Float = 0f) {
translationX.animateTo(targetValue = drawerWidth, initialVelocity = velocity)
drawerState = DrawerState.Open
}

val velocityTracker = remember {
VelocityTracker()
}

// [START android_compose_predictivebackhandler]
PredictiveBackHandler(drawerState == DrawerState.Open) { progress ->
try {
progress.collect { backEvent ->
val targetSize = (drawerWidth - (drawerWidth * backEvent.progress))
translationX.snapTo(targetSize)
velocityTracker.addPosition(
SystemClock.uptimeMillis(),
Offset(backEvent.touchX, backEvent.touchY)
)
}
closeDrawer(velocityTracker.calculateVelocity().x)
} catch (e: CancellationException) {
openDrawer(velocityTracker.calculateVelocity().x)
}
velocityTracker.resetTracking()
}
// [END android_compose_predictivebackhandler]

}
}

private enum class DrawerState {
Open,
Closed
}

private val DrawerWidth = 300.dp