It seems like the composable NavHost
from androidx.navigation:navigation-compose:2.5.3
does not satisfy navigation principles for back-button navigation as outlined here: https://developer.android.com/guide/navigation/navigation-principles
In particular: When opening the app using a deep link, the back button traverses up the app back stack, but it should leave the app instead. Am I missing anything? What can I do to correct the behavior?
Back-button behavior when opening the app with a details deep-link:
Example code to demonstrate this: AndroidManifest.xml: Add deep link support
<application>
...
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
<data android:scheme="http"
android:host="www.example.com"
android:pathPrefix="/gizmos" />
<!-- note that the leading "/" is required for pathPrefix-->
</intent-filter>
</application
MainActivity.kt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyApplicationTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainNavigation()
}
}
}
}
}
@Composable
fun MainNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "start") {
navigation(
startDestination = "list",
route = "start",
) {
composable("list") { ListScreen(navigateToDetail = {
navController.navigate(route = "detail/$it")
}) }
composable(
route = "detail/{id}",
arguments = listOf(
navArgument(name = "id") { type = NavType.LongType }
),
deepLinks = listOf(
navDeepLink {
uriPattern = "http://www.example.com/gizmos/{id}"
}
)
) { backStackEntry ->
val id = backStackEntry.arguments?.getLong("id")
DetailScreen(id)
}
}
// TODO: Add more destinations
}
}
@Composable
fun ListScreen(
navigateToDetail : (Long) -> Unit,
) {
Text("List")
Button(onClick = {
navigateToDetail(42)
}) {
Text("Navigate to 42")
}
}
@Composable
fun DetailScreen(
id : Long?,
) {
Text("Detail: $id")
}
The issue was not with jetpack compose navigation, but with the way I navigated to the app.
When opening the app through an intent via adb, like in ./adb shell am start -W -a android.intent.action.VIEW -d "http://www.example.com/gizmos/1234" com.example.navanimation
, then the intent isn't called from another app task and therefore the back button shouldn't navigate to the app that was open previously.