From 81b4e8b391d598e17c26cb5af15f5656f742aa22 Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Mon, 4 Nov 2024 15:04:15 -0800 Subject: [PATCH 1/7] add in predictive back snippets for NavHost and predictive back handler --- .../predictiveback/PredictiveBackSnippets.kt | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt new file mode 100644 index 000000000..82e3a52da --- /dev/null +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -0,0 +1,137 @@ +package com.example.compose.snippets.predictiveback + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import androidx.compose.animation.scaleOut +import androidx.compose.ui.graphics.TransformOrigin +import android.os.SystemClock +import androidx.activity.compose.PredictiveBackHandler +import androidx.compose.animation.core.Animatable +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material.icons.filled.Home +import androidx.compose.material3.Surface +import androidx.compose.material3.windowsizeclass.WindowSizeClass +import androidx.compose.runtime.Composable +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.Modifier +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 +import kotlinx.coroutines.launch + + +@Composable +fun MainNavigation( + 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 +fun HomeScreenDrawer(windowSizeClass: WindowSizeClass) { + + Surface( + modifier = Modifier.fillMaxSize() + ) { + var drawerState by remember { + mutableStateOf(DrawerState.Closed) + } + var screenState by remember { + mutableStateOf(Screen.Home) + } + + 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 + } + fun toggleDrawerState() { + coroutineScope.launch { + if (drawerState == DrawerState.Open) { + closeDrawer() + } else { + openDrawer() + } + } + } + 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 +} From ba6aaa4925f6947308609f51739067ac8938efa7 Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Mon, 4 Nov 2024 15:18:27 -0800 Subject: [PATCH 2/7] add in expression --- .../compose/snippets/predictiveback/PredictiveBackSnippets.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt index 82e3a52da..212ad518f 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -60,6 +60,7 @@ fun MainNavigation( SettingsScreen( modifier = modifier, navController = navController, + ) } } } From 63a7c176e004996f4478d5a0d96ab72870f27ca6 Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Mon, 4 Nov 2024 15:34:38 -0800 Subject: [PATCH 3/7] fix build errors --- .../predictiveback/PredictiveBackSnippets.kt | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt index 212ad518f..c77f3726c 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -2,24 +2,23 @@ package com.example.compose.snippets.predictiveback import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController 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.navigation.compose.NavHost import androidx.compose.animation.core.Animatable +import androidx.navigation.compose.composable import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material.icons.filled.Home import androidx.compose.material3.Surface -import androidx.compose.material3.windowsizeclass.WindowSizeClass -import androidx.compose.runtime.Composable 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.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.pointer.util.VelocityTracker import androidx.compose.ui.platform.LocalDensity @@ -66,7 +65,19 @@ fun MainNavigation( } @Composable -fun HomeScreenDrawer(windowSizeClass: WindowSizeClass) { +fun HomeScreen( + modifier: Modifier = Modifier, navController: NavHostController +) { + +} + +@Composable +fun SettingsScreen( + modifier: Modifier = Modifier, navController: NavHostController +) { + +@Composable +fun HomeScreenDrawer() { Surface( modifier = Modifier.fillMaxSize() From fbf7c6f63e8d3a439f3c5fbcf3948d81764915cb Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Mon, 4 Nov 2024 16:10:06 -0800 Subject: [PATCH 4/7] fix build error --- .../compose/snippets/predictiveback/PredictiveBackSnippets.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt index c77f3726c..d99fe3850 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -76,6 +76,8 @@ fun SettingsScreen( modifier: Modifier = Modifier, navController: NavHostController ) { +} + @Composable fun HomeScreenDrawer() { @@ -147,3 +149,4 @@ private enum class DrawerState { Open, Closed } + From 370231a5238f7ca560a471e34b8b342fb2160651 Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Tue, 5 Nov 2024 14:40:32 -0800 Subject: [PATCH 5/7] rename composables to be more descriptive and make it private --- .../predictiveback/PredictiveBackSnippets.kt | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt index d99fe3850..cadda6f9b 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -2,6 +2,7 @@ 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.compose.animation.scaleOut import androidx.compose.ui.graphics.TransformOrigin @@ -12,7 +13,6 @@ import androidx.navigation.compose.NavHost import androidx.compose.animation.core.Animatable import androidx.navigation.compose.composable import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material.icons.filled.Home import androidx.compose.material3.Surface import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -23,11 +23,10 @@ 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 -import kotlinx.coroutines.launch @Composable -fun MainNavigation( +private fun PredictiveBackOverrideExit( modifier: Modifier, ) { val navController = rememberNavController() @@ -79,7 +78,7 @@ fun SettingsScreen( } @Composable -fun HomeScreenDrawer() { +private fun PredictiveBackHandlerManualProgress() { Surface( modifier = Modifier.fillMaxSize() @@ -87,9 +86,6 @@ fun HomeScreenDrawer() { var drawerState by remember { mutableStateOf(DrawerState.Closed) } - var screenState by remember { - mutableStateOf(Screen.Home) - } val translationX = remember { Animatable(0f) @@ -110,15 +106,7 @@ fun HomeScreenDrawer() { translationX.animateTo(targetValue = drawerWidth, initialVelocity = velocity) drawerState = DrawerState.Open } - fun toggleDrawerState() { - coroutineScope.launch { - if (drawerState == DrawerState.Open) { - closeDrawer() - } else { - openDrawer() - } - } - } + val velocityTracker = remember { VelocityTracker() } From deed71810eb95403fcff7cc0390b5a6aca0fa631 Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Tue, 5 Nov 2024 15:59:17 -0800 Subject: [PATCH 6/7] fix build errors --- .../snippets/predictiveback/PredictiveBackSnippets.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt index cadda6f9b..1b098074e 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -9,7 +9,6 @@ import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.animation.EnterTransition import android.os.SystemClock import androidx.activity.compose.PredictiveBackHandler -import androidx.navigation.compose.NavHost import androidx.compose.animation.core.Animatable import androidx.navigation.compose.composable import androidx.compose.foundation.layout.fillMaxSize @@ -64,14 +63,14 @@ private fun PredictiveBackOverrideExit( } @Composable -fun HomeScreen( +private fun HomeScreen( modifier: Modifier = Modifier, navController: NavHostController ) { } @Composable -fun SettingsScreen( +private fun SettingsScreen( modifier: Modifier = Modifier, navController: NavHostController ) { From 1527d9aa621ca9058b9f28a023d7452718204dc2 Mon Sep 17 00:00:00 2001 From: Tram Bui Date: Tue, 5 Nov 2024 16:16:03 -0800 Subject: [PATCH 7/7] fix build errors --- .../compose/snippets/predictiveback/PredictiveBackSnippets.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt index 1b098074e..f0489c14f 100644 --- a/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt +++ b/compose/snippets/src/main/java/com/example/compose/snippets/predictiveback/PredictiveBackSnippets.kt @@ -4,11 +4,13 @@ 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 @@ -137,3 +139,5 @@ private enum class DrawerState { Closed } +private val DrawerWidth = 300.dp +