Fluxos de login, assistentes ou outros subfluxos no seu app geralmente são mais bem representados como gráficos de navegação aninhados. Aninhando fluxos de subnavegação autocontidos dessa forma, fica mais fácil de compreender e gerenciar o fluxo principal da interface do seu app.
Além disso, os gráficos aninhados são reutilizáveis. Eles também oferecem um nível de
encapsulamento: destinos fora do gráfico aninhado não têm acesso direto
a nenhum dos destinos dentro do gráfico aninhado. Em vez disso, eles precisam
navigate()
até o gráfico aninhado, onde a lógica interna pode
mudar sem afetar o resto do gráfico.
Exemplo
O gráfico de navegação de nível superior do seu app precisa começar com o destino inicial que o usuário encontra ao iniciar o app e incluir os destinos que ele vê quando se movimenta pelo app.
![](https://developer.android.com/static/images/topic/libraries/architecture/navigation-design-graph-top-level.png?authuser=9&hl=pt)
Usando o gráfico de navegação de nível superior da Figura 1 como exemplo, suponha que você queria exigir que o usuário visse as telas title_screen e register. somente quando o app é iniciado pela primeira vez. Em seguida, as informações do usuário são armazenados e, em inicializações subsequentes do app, você deve levá-los diretamente para a tela match.
Como prática recomendada, defina a tela match como o destino inicial do gráfico de navegação de nível superior e mover as telas de título e registro para um gráfico, conforme mostrado na Figura 1:
![](https://developer.android.com/static/images/topic/libraries/architecture/navigation-design-graph-nested.png?authuser=9&hl=pt)
Quando a tela de correspondência for iniciada, verifique se há um usuário registrado. Se o usuário não estiver registrado, navegue até a tela de registro.
Para saber mais sobre cenários de navegação condicional, consulte Navegação condicional.
Compose
Para criar um gráfico de navegação aninhado usando o Compose, use a
função NavGraphBuilder.navigation()
. Use navigation()
da mesma forma que as funções
NavGraphBuilder.composable()
e NavGraphBuilder.dialog()
ao adicionar destinos a um gráfico.
A principal diferença é que navigation
cria um gráfico aninhado em vez de um
novo destino. Em seguida, você vai chamar composable()
e dialog()
O lambda de navigation()
para adicionar destinos ao gráfico aninhado.
Considere como o snippet abaixo implementa o gráfico na Figura 2 usando o Compose:
// Routes
@Serializable object Title
@Serializable object Register
// Route for nested graph
@Serializable object Game
// Routes inside nested graph
@Serializable object Match
@Serializable object InGame
@Serializable object ResultsWinner
@Serializable object GameOver
NavHost(navController, startDestination = Title) {
composable<Title> {
TitleScreen(
onPlayClicked = { navController.navigate(route = Register) },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<Register> {
RegisterScreen(
onSignUpComplete = { navController.navigate(route = Game) }
)
}
navigation<Game>(startDestination = Match) {
composable<Match> {
MatchScreen(
onStartGame = { navController.navigate(route = InGame) }
)
}
composable<InGame> {
InGameScreen(
onGameWin = { navController.navigate(route = ResultsWinner) },
onGameLose = { navController.navigate(route = GameOver) }
)
}
composable<ResultsWinner> {
ResultsWinnerScreen(
onNextMatchClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
},
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<GameOver> {
GameOverScreen(
onTryAgainClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
}
)
}
}
}
Para navegar diretamente até um destino aninhado, use um tipo de rota como faria para qualquer outro destino. Isso ocorre porque as rotas são um conceito global usado para identificar destinos para os quais qualquer tela pode navegar:
navController.navigate(route = Match)
XML
Ao usar XML, você pode usar o Navigation Editor para criar seu gráfico aninhado. Para isso, siga estas etapas:
- No Navigation Editor, toque e pressione a tecla Shift, e clique nos destinos que você quer incluir no gráfico aninhado.
Clique com o botão direito do mouse para abrir o menu de contexto e selecione Move to Nested Graph > New Graph. Os destinos são colocados em um gráfico aninhado. A Figura 2 mostra um gráfico aninhado no Navigation Editor:
Figura 2. Gráfico aninhado no Navigation Editor Clique no gráfico aninhado. Os atributos abaixo aparecem no painel Attributes:
- Type contém o "Nested Graph".
- ID contém um ID atribuído pelo sistema ao gráfico aninhado. Isso O ID é usado para fazer referência ao gráfico aninhado do código.
Clique duas vezes no gráfico aninhado para exibir os destinos.
Clique na guia Text para alternar para a visualização XML. Um gráfico de navegação aninhado foi adicionado ao gráfico. Este gráfico de navegação tem os próprios elementos
navigation
, com o ID e um atributostartDestination
que aponta para o primeiro destino no gráfico aninhado:<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.cashdog.cashdog.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main" > <action android:id="@+id/action_mainFragment_to_sendMoneyGraph" app:destination="@id/sendMoneyGraph" /> <action android:id="@+id/action_mainFragment_to_viewBalanceFragment" app:destination="@id/viewBalanceFragment" /> </fragment> <fragment android:id="@+id/viewBalanceFragment" android:name="com.example.cashdog.cashdog.ViewBalanceFragment" android:label="fragment_view_balance" tools:layout="@layout/fragment_view_balance" /> <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient"> <fragment android:id="@+id/chooseRecipient" android:name="com.example.cashdog.cashdog.ChooseRecipient" android:label="fragment_choose_recipient" tools:layout="@layout/fragment_choose_recipient"> <action android:id="@+id/action_chooseRecipient_to_chooseAmountFragment" app:destination="@id/chooseAmountFragment" /> </fragment> <fragment android:id="@+id/chooseAmountFragment" android:name="com.example.cashdog.cashdog.ChooseAmountFragment" android:label="fragment_choose_amount" tools:layout="@layout/fragment_choose_amount" /> </navigation> </navigation>
No seu código, transmita o ID do recurso da ação que conecta o gráfico raiz ao gráfico aninhado:
Kotlin
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
Java
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- De volta à guia Design, retorne ao gráfico raiz clicando em Root.
Fazer referência a outros gráficos de navegação com "include"
Outra maneira de modularizar a estrutura do seu gráfico é incluir um gráfico dentro
de outro usando um elemento <include>
no gráfico de navegação pai. Isso
permite que o gráfico incluído seja definido em um módulo ou projeto separado, o que
maximiza a capacidade de reutilização.
O snippet abaixo demonstra como usar <include>
:
<!-- (root) nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/fragment">
<strong><include app:graph="@navigation/included_graph" /></strong>
<fragment
android:id="@+id/fragment"
android:name="com.example.myapplication.BlankFragment"
android:label="Fragment in Root Graph"
tools:layout="@layout/fragment_blank">
<strong><action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" /></strong>
</fragment>
...
</navigation>
<!-- included_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<strong>android:id="@+id/second_graph"</strong>
app:startDestination="@id/includedStart">
<fragment
android:id="@+id/includedStart"
android:name="com.example.myapplication.IncludedStart"
android:label="fragment_included_start"
tools:layout="@layout/fragment_included_start" />
</navigation>
Outros recursos
Para saber mais sobre navegação, consulte os recursos adicionais a seguir.
Amostras
- NavigationBasicSample (link em inglês)