Skip to content

Commit 81b4e8b

Browse files
committed
add in predictive back snippets for NavHost and predictive back handler
1 parent d081491 commit 81b4e8b

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
package com.example.compose.snippets.predictiveback
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.ui.Modifier
5+
import androidx.navigation.compose.composable
6+
import androidx.navigation.compose.rememberNavController
7+
import androidx.compose.animation.scaleOut
8+
import androidx.compose.ui.graphics.TransformOrigin
9+
import android.os.SystemClock
10+
import androidx.activity.compose.PredictiveBackHandler
11+
import androidx.compose.animation.core.Animatable
12+
import androidx.compose.foundation.layout.fillMaxSize
13+
import androidx.compose.material.icons.filled.Home
14+
import androidx.compose.material3.Surface
15+
import androidx.compose.material3.windowsizeclass.WindowSizeClass
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
20+
import androidx.compose.runtime.rememberCoroutineScope
21+
import androidx.compose.runtime.setValue
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.geometry.Offset
24+
import androidx.compose.ui.input.pointer.util.VelocityTracker
25+
import androidx.compose.ui.platform.LocalDensity
26+
import kotlin.coroutines.cancellation.CancellationException
27+
import kotlinx.coroutines.launch
28+
29+
30+
@Composable
31+
fun MainNavigation(
32+
modifier: Modifier,
33+
) {
34+
val navController = rememberNavController()
35+
36+
// [START android_compose_predictiveback_navhost]
37+
NavHost(
38+
navController = navController,
39+
startDestination = "home",
40+
popExitTransition = {
41+
scaleOut(
42+
targetScale = 0.9f,
43+
transformOrigin = TransformOrigin(pivotFractionX = 0.5f, pivotFractionY = 0.5f)
44+
)
45+
},
46+
popEnterTransition = {
47+
EnterTransition.None
48+
},
49+
modifier = modifier,
50+
)
51+
// [END android_compose_predictiveback_navhost]
52+
{
53+
composable("home") {
54+
HomeScreen(
55+
modifier = modifier,
56+
navController = navController,
57+
)
58+
}
59+
composable("settings") {
60+
SettingsScreen(
61+
modifier = modifier,
62+
navController = navController,
63+
}
64+
}
65+
}
66+
67+
@Composable
68+
fun HomeScreenDrawer(windowSizeClass: WindowSizeClass) {
69+
70+
Surface(
71+
modifier = Modifier.fillMaxSize()
72+
) {
73+
var drawerState by remember {
74+
mutableStateOf(DrawerState.Closed)
75+
}
76+
var screenState by remember {
77+
mutableStateOf(Screen.Home)
78+
}
79+
80+
val translationX = remember {
81+
Animatable(0f)
82+
}
83+
84+
val drawerWidth = with(LocalDensity.current) {
85+
DrawerWidth.toPx()
86+
}
87+
translationX.updateBounds(0f, drawerWidth)
88+
89+
val coroutineScope = rememberCoroutineScope()
90+
91+
suspend fun closeDrawer(velocity: Float = 0f) {
92+
translationX.animateTo(targetValue = 0f, initialVelocity = velocity)
93+
drawerState = DrawerState.Closed
94+
}
95+
suspend fun openDrawer(velocity: Float = 0f) {
96+
translationX.animateTo(targetValue = drawerWidth, initialVelocity = velocity)
97+
drawerState = DrawerState.Open
98+
}
99+
fun toggleDrawerState() {
100+
coroutineScope.launch {
101+
if (drawerState == DrawerState.Open) {
102+
closeDrawer()
103+
} else {
104+
openDrawer()
105+
}
106+
}
107+
}
108+
val velocityTracker = remember {
109+
VelocityTracker()
110+
}
111+
112+
// [START android_compose_predictivebackhandler]
113+
PredictiveBackHandler(drawerState == DrawerState.Open) { progress ->
114+
try {
115+
progress.collect { backEvent ->
116+
val targetSize = (drawerWidth - (drawerWidth * backEvent.progress))
117+
translationX.snapTo(targetSize)
118+
velocityTracker.addPosition(
119+
SystemClock.uptimeMillis(),
120+
Offset(backEvent.touchX, backEvent.touchY)
121+
)
122+
}
123+
closeDrawer(velocityTracker.calculateVelocity().x)
124+
} catch (e: CancellationException) {
125+
openDrawer(velocityTracker.calculateVelocity().x)
126+
}
127+
velocityTracker.resetTracking()
128+
}
129+
// [END android_compose_predictivebackhandler]
130+
131+
}
132+
}
133+
134+
private enum class DrawerState {
135+
Open,
136+
Closed
137+
}

0 commit comments

Comments
 (0)