Skip to content

Commit fd7d481

Browse files
add Tutorial2_3PopBackStackWithResult
1 parent f1cbeb7 commit fd7d481

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
package com.smarttoolfactory.tutorial3_1navigation
2+
3+
import android.annotation.SuppressLint
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Spacer
6+
import androidx.compose.foundation.layout.fillMaxSize
7+
import androidx.compose.foundation.layout.fillMaxWidth
8+
import androidx.compose.foundation.layout.height
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.text.KeyboardOptions
11+
import androidx.compose.material3.Button
12+
import androidx.compose.material3.OutlinedTextField
13+
import androidx.compose.material3.Text
14+
import androidx.compose.runtime.Composable
15+
import androidx.compose.runtime.collectAsState
16+
import androidx.compose.runtime.getValue
17+
import androidx.compose.runtime.mutableIntStateOf
18+
import androidx.compose.runtime.remember
19+
import androidx.compose.runtime.setValue
20+
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.text.input.KeyboardType
22+
import androidx.compose.ui.tooling.preview.Preview
23+
import androidx.compose.ui.unit.dp
24+
import androidx.compose.ui.unit.sp
25+
import androidx.lifecycle.compose.dropUnlessResumed
26+
import androidx.navigation.NavBackStackEntry
27+
import androidx.navigation.NavGraph.Companion.findStartDestination
28+
import androidx.navigation.compose.NavHost
29+
import androidx.navigation.compose.composable
30+
import androidx.navigation.compose.rememberNavController
31+
import kotlinx.serialization.Serializable
32+
33+
34+
sealed class MyNavigation {
35+
@Serializable
36+
data class Home(
37+
val id: Int,
38+
) : MyNavigation()
39+
40+
@Serializable
41+
data object Detail : MyNavigation()
42+
43+
@Serializable
44+
data object Final : MyNavigation()
45+
}
46+
47+
@SuppressLint("RestrictedApi")
48+
@Preview
49+
@Composable
50+
fun PopUpBackStackWithResultSample() {
51+
val navController = rememberNavController()
52+
53+
NavHost(
54+
modifier = Modifier.fillMaxSize(),
55+
navController = navController,
56+
startDestination = MyNavigation.Home(-1)
57+
) {
58+
composable<MyNavigation.Home> { navBackstackEntry: NavBackStackEntry ->
59+
val id = navBackstackEntry.savedStateHandle.get<Int>("id") ?: 0
60+
61+
HomeScreen(
62+
id = id,
63+
onNavigateToDetail = { navController.navigate(MyNavigation.Detail) }
64+
)
65+
}
66+
67+
composable<MyNavigation.Detail> {
68+
DetailScreen(
69+
onNavigateToFinal = { navController.navigate(MyNavigation.Final) }
70+
)
71+
}
72+
73+
composable<MyNavigation.Final> {
74+
75+
val backStack by navController.currentBackStack.collectAsState()
76+
77+
FinalScreen(
78+
onNavigateBackToHome = { newId ->
79+
val startId = navController.graph.findStartDestination().id
80+
navController.getBackStackEntry(startId).savedStateHandle["id"] = newId
81+
navController.popBackStack(
82+
destinationId = startId,
83+
inclusive = false
84+
)
85+
86+
// Alternative for getting NavDestination
87+
/* val firstDestination: NavDestination? = backStack.firstOrNull {
88+
it.destination.hasRoute(MyNavigation.Home::class)
89+
}?.destination
90+
91+
firstDestination?.let {
92+
val startId = firstDestination.id
93+
94+
navController.getBackStackEntry(startId).savedStateHandle["id"] = newId
95+
96+
navController.popBackStack(
97+
destinationId = startId,
98+
inclusive = false
99+
)
100+
}*/
101+
}
102+
)
103+
}
104+
}
105+
}
106+
107+
@Composable
108+
private fun HomeScreen(id: Int, onNavigateToDetail: () -> Unit) {
109+
110+
Column(
111+
modifier = Modifier.fillMaxSize().padding(16.dp),
112+
113+
) {
114+
Text("Home Screen Id: $id", fontSize = 32.sp)
115+
116+
Spacer(Modifier.weight(1f))
117+
Button(
118+
modifier = Modifier.fillMaxWidth(),
119+
onClick = onNavigateToDetail
120+
) {
121+
Text("Navigate to detail")
122+
}
123+
}
124+
}
125+
126+
@Composable
127+
private fun DetailScreen(onNavigateToFinal: () -> Unit) {
128+
Column(
129+
modifier = Modifier.fillMaxSize().padding(16.dp)
130+
) {
131+
132+
Text("Detail Screen", fontSize = 32.sp)
133+
Spacer(Modifier.weight(1f))
134+
Button(
135+
modifier = Modifier.fillMaxWidth(),
136+
onClick = onNavigateToFinal
137+
) {
138+
Text("Navigate to Final")
139+
}
140+
}
141+
}
142+
143+
@Composable
144+
private fun FinalScreen(onNavigateBackToHome: (Int) -> Unit) {
145+
Column(
146+
modifier = Modifier.fillMaxSize().padding(16.dp)
147+
) {
148+
149+
var newId by remember {
150+
mutableIntStateOf(0)
151+
}
152+
Text("Final Screen", fontSize = 32.sp)
153+
154+
Spacer(Modifier.height(60.dp))
155+
156+
OutlinedTextField(
157+
modifier = Modifier.fillMaxWidth(),
158+
value = newId.toString(),
159+
onValueChange = { text ->
160+
text.toIntOrNull()?.let {
161+
newId = it
162+
}
163+
},
164+
keyboardOptions = KeyboardOptions(
165+
keyboardType = KeyboardType.NumberPassword
166+
)
167+
)
168+
Spacer(Modifier.weight(1f))
169+
170+
Button(
171+
modifier = Modifier.fillMaxWidth(),
172+
onClick = dropUnlessResumed {
173+
onNavigateBackToHome(newId)
174+
}
175+
) {
176+
Text("Popup back to Home")
177+
}
178+
}
179+
}

0 commit comments

Comments
 (0)