O componente Navigation usa um gráfico de navegação para gerenciar a navegação do seu app. O gráfico de navegação é uma estrutura de dados que contém cada destino no app e as conexões entre eles.
Tipos de destino
Existem três tipos gerais de destinos: hospedado, caixa de diálogo e atividade. A tabela abaixo descreve esses três tipos de destino e as finalidades deles.
Tipo |
Descrição |
Casos de uso |
---|---|---|
Hospedado |
Preenche todo o host de navegação. Ou seja, o tamanho de um destino hospedado é o mesmo do host de navegação, e os destinos anteriores não são visíveis. |
Telas principal e de detalhes. |
Caixa de diálogo |
Apresenta componentes de interface de sobreposição. Essa interface não está vinculada ao local nem ao tamanho do host de navegação. Os destinos anteriores ficam visíveis abaixo dele. |
Alertas, seleções, formulários. |
Atividade |
Representa telas ou recursos únicos no app. |
Serve como um ponto de saída para o gráfico de navegação que inicia uma nova atividade do Android gerenciada separadamente do componente Navigation. No Modern Android Development, um app consiste em uma única atividade. Os destinos de atividade são mais indicados para interagir com atividades de terceiros ou como parte do processo de migração. |
Este documento contém exemplos de destinos hospedados, que são os destinos mais comuns e fundamentais. Consulte os guias abaixo para mais informações sobre outros destinos:
Estruturas de trabalho
Embora o mesmo fluxo de trabalho geral se aplique a todos os casos, a maneira exata de criar um host e um gráfico de navegação depende do framework da interface que você usa.
- Compose: use o elemento combinável
NavHost
. Adicione umNavGraph
a ele usando a DSL do Kotlin. É possível criar o gráfico de duas maneiras:- Como parte do NavHost: construa o gráfico de navegação diretamente como
parte da adição do
NavHost
. - De forma programática: use o método
NavController.createGraph()
para criar umNavGraph
e transmiti-lo diretamente para oNavHost
.
- Como parte do NavHost: construa o gráfico de navegação diretamente como
parte da adição do
- Fragmentos:ao usar fragmentos com o framework de interface de visualizações, use um
NavHostFragment
como host. Há várias maneiras de criar um gráfico de navegação:- De forma programática:use a DSL do Kotlin para criar um
NavGraph
e aplicá-lo diretamente aoNavHostFragment
.- A função
createGraph()
usada com a DSL do Kotlin para fragmentos e Compose é a mesma.
- A função
- XML: programe o host e o gráfico de navegação diretamente em XML.
- Editor do Android Studio: use o editor de GUI no Android Studio para criar e ajustar o gráfico como um arquivo de recurso XML.
- De forma programática:use a DSL do Kotlin para criar um
Escrever
No Compose, use um objeto ou classe serializável para definir uma rota. Um trajeto descreve como chegar a um destino e contém todas as informações necessárias para chegar até ele.
Use a anotação @Serializable
para criar automaticamente os métodos de serialização e desserialização
necessários para os tipos de rota. Essa anotação
é fornecida pelo plug-in de serialização
do Kotlin. Siga estas
instruções para adicionar este plug-in.
Depois de definir as rotas, use o elemento combinável NavHost
para criar o
gráfico de navegação. Veja o exemplo a seguir:
@Serializable
object Profile
@Serializable
object FriendsList
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
// Add more destinations similarly.
}
- Um objeto serializável representa cada uma das duas rotas,
Profile
eFriendsList
. - A chamada para o elemento combinável
NavHost
transmite umaNavController
e uma rota para o destino inicial. - A lambda transmitida ao
NavHost
chamaNavController.createGraph()
e retorna umNavGraph
. - Cada rota é fornecida como um argumento de tipo para
NavGraphBuilder.composable<T>()
, que adiciona o destino àNavGraph
resultante. - A lambda transmitida para
composable
é o que oNavHost
mostra para esse destino.
Entender a lambda
Para entender melhor a lambda que cria o NavGraph
, considere que, para
criar o mesmo gráfico do snippet anterior, você poderia criar o
NavGraph
separadamente usando NavController.createGraph()
e transmitindo diretamente para o
NavHost
:
val navGraph by remember(navController) {
navController.createGraph(startDestination = Profile)) {
composable<Profile> { ProfileScreen( /* ... */ ) }
composable<FriendsList> { FriendsListScreen( /* ... */ ) }
}
}
NavHost(navController, navGraph)
Transmitir argumentos
Se você precisar transmitir dados para um destino, defina a rota com uma classe que
tenha parâmetros. Por exemplo, a rota Profile
é uma classe de dados com um parâmetro
name
.
@Serializable
data class Profile(val name: String)
Sempre que precisar transmitir argumentos para esse destino, crie uma instância da classe de rota, transmitindo os argumentos para o construtor da classe.
Para argumentos opcionais, crie campos anuláveis com um valor padrão.
@Serializable
data class Profile(val nickname: String? = null)
Extrair instância de rota
É possível acessar a instância de rota com NavBackStackEntry.toRoute()
ou
SavedStateHandle.toRoute()
. Quando você cria um destino usando
composable()
, o NavBackStackEntry
fica disponível como um parâmetro.
@Serializable
data class Profile(val name: String)
val navController = rememberNavController()
NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(name = profile.name) }
}
Observe o seguinte neste snippet:
- A rota
Profile
especifica o destino inicial no gráfico de navegação, com"John Smith"
como o argumento paraname
. - O destino é o bloco
composable<Profile>{}
. - O elemento combinável
ProfileScreen
assume o valor deprofile.name
para o próprio argumentoname
. - Assim, o valor
"John Smith"
é transmitido paraProfileScreen
.
Exemplo mínimo
Um exemplo completo de NavController
e NavHost
trabalhando juntos:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
profile: Profile
onNavigateToFriendsList: () -> Unit,
) {
Text("Profile for ${profile.name}")
Button(onClick = { onNavigateToFriendsList() }) {
Text("Go to Friends List")
}
}
// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
Text("Friends List")
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
val navController = rememberNavController()
NavHost(navController, startDestination = Profile(name = "John Smith")) {
composable<Profile> { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(
profile = profile,
onNavigateToFriendsList = {
navController.navigate(route = FriendsList)
}
)
}
composable<FriendsList> {
FriendsListScreen(
onNavigateToProfile = {
navController.navigate(
route = Profile(name = "Aisha Devi")
)
}
)
}
}
}
Como demonstrado no snippet, em vez de transmitir o NavController
para os
elementos combináveis, exponha um evento para o NavHost
. Ou seja, os elementos combináveis precisam
ter um parâmetro do tipo () -> Unit
para o qual o NavHost
transmite uma lambda
que chama NavController.navigate()
.
Fragmentos
Conforme descrito nas seções anteriores, ao usar fragmentos, você tem a opção de criar um gráfico de navegação de forma programática usando a DSL do Kotlin, o XML ou o editor do Android Studio.
As seções abaixo detalham essas diferentes abordagens.
De forma programática
A DSL do Kotlin oferece uma maneira programática de criar um gráfico de navegação com fragmentos. Isso acaba ficando mais bem organizado e moderno do que usar um arquivo de recurso XML.
Confira o exemplo abaixo, que implementa um gráfico de navegação em duas telas.
Primeiro, é necessário criar o NavHostFragment
, que não pode incluir
um elemento app:navGraph
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Em seguida, transmita o id
do NavHostFragment
para
NavController.findNavController
. Isso associa o NavController ao
NavHostFragment
.
Em seguida, a chamada para NavController.createGraph()
vincula o gráfico ao
NavController
e, consequentemente, também ao NavHostFragment
:
@Serializable
data class Profile(val name: String)
@Serializable
object FriendsList
// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)
// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
startDestination = Profile(name = "John Smith")
) {
// Associate each destination with one of the route constants.
fragment<ProfileFragment, Profile> {
label = "Profile"
}
fragment<FriendsListFragment, FriendsList>() {
label = "Friends List"
}
// Add other fragment destinations similarly.
}
O uso da DSL dessa maneira é muito semelhante ao fluxo de trabalho descrito na
seção anterior no Compose. Por exemplo, lá e aqui, a
função NavController.createGraph()
gera o NavGraph
. Da mesma forma, enquanto
NavGraphBuilder.composable()
adiciona destinos combináveis ao gráfico, aqui
NavGraphBuilder.fragment()
adiciona um destino de fragmento.
Para saber mais sobre como usar a DSL do Kotlin, consulte Criar um gráfico com a DSL do NavGraphBuilder.
XML
Você pode criar o XML diretamente. O exemplo abaixo espelha e é equivalente ao exemplo de duas telas da seção anterior.
Primeiro, crie um NavHostFragment
. Ele serve como o host de navegação, que
contém o gráfico de navegação real.
Uma implementação mínima de um NavHostFragment
:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/nav_graph" />
</FrameLayout>
O NavHostFragment
contém o atributo app:navGraph
. Use esse atributo
para conectar seu gráfico de navegação ao host de navegação. Confira abaixo um
exemplo de como implementar o gráfico:
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_graph"
app:startDestination="@id/profile">
<fragment
android:id="@+id/profile"
android:name="com.example.ProfileFragment"
android:label="Profile">
<!-- Action to navigate from Profile to Friends List. -->
<action
android:id="@+id/action_profile_to_friendslist"
app:destination="@id/friendslist" />
</fragment>
<fragment
android:id="@+id/friendslist"
android:name="com.example.FriendsListFragment"
android:label="Friends List" />
<!-- Add other fragment destinations similarly. -->
</navigation>
Você usa ações para definir as conexões entre destinos diferentes. Neste
exemplo, o fragmento profile
contém uma ação que navega para
friendslist
. Para saber mais, consulte Usar ações e
fragmentos de navegação.
Editor
Você pode gerenciar o gráfico de navegação do seu app usando o Navigation Editor no
Android Studio. Essencialmente, essa é uma GUI que pode ser usada para criar e editar o
XML do NavigationFragment
, conforme mostrado na seção anterior.
Para mais informações, consulte o Navigation Editor.
Gráficos aninhados
Também é possível usar gráficos aninhados. Isso envolve o uso de um gráfico como destino de navegação. Para mais informações, consulte Gráficos aninhados.
Leia mais
Para conferir mais dos principais conceitos de navegação, consulte os guias abaixo:
- Visão geral: leia a visão geral do componente Navigation.
- Destinos de atividade: exemplos de como implementar destinos que levam o usuário a atividades.
- Destinos de caixa de diálogo: exemplos de como criar destinos que levam o usuário a uma caixa de diálogo.
- Navegar até um destino: um guia detalhado sobre como navegar de um destino para outro.
- Gráficos aninhados:um guia detalhado sobre como aninhar um gráfico de navegação em outro.