Um gráfico de navegação pode consistir em qualquer combinação dos itens a seguir:
- Um destino singular, como
<fragment>
. - Um gráfico aninhado que encapsula um conjunto de destinos relacionados.
- Um elemento
<include>
, que permite incorporar outro arquivo de gráfico de navegação como se ele estivesse aninhado.
Essa flexibilidade permite combinar gráficos de navegação menores para formar o gráfico de navegação completo do app, mesmo que esses gráficos menores sejam fornecidos por módulos de biblioteca separados.
Para os exemplos deste tópico, cada módulo de biblioteca se concentra em um
recurso e fornece um único gráfico de navegação que encapsula todos os
destinos necessários para implementar esse recurso. Em um app de produção, você pode
ter muitos submódulos em um nível inferior, que são detalhes de implementação desse
módulo de biblioteca de nível superior. Cada um desses módulos de biblioteca é incluído,
direta ou indiretamente, no módulo app
. O aplicativo de exemplo
de vários módulos usado neste documento tem esta estrutura:


Cada módulo de biblioteca é uma unidade independente com o próprio gráfico de navegação
e os destinos. O módulo app
depende deles, adicionando-os como
detalhes de implementação no arquivo build.gradle
, conforme mostrado a seguir:
dependencies {
...
implementation project(":list")
implementation project(":favorites")
implementation project(":settings")
O papel do módulo app
O módulo app
é responsável por fornecer o gráfico completo do
app e adicionar o NavHost
à IU. No gráfico de navegação do módulo
app
, você pode referenciar os gráficos da biblioteca usando
<include>
. Embora
o uso de <include>
seja funcionalmente o mesmo que usar um gráfico aninhado,
<include>
é compatível com gráficos de outros módulos do projeto ou de projetos de
biblioteca, como mostrado no exemplo a seguir:
<?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/list_nav_graph">
<include app:graph="@navigation/list_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
</navigation>
Quando uma biblioteca for incluída no gráfico de navegação de nível superior, será possível navegar pelos gráficos da biblioteca conforme necessário. Por exemplo, você pode criar uma ação para navegar até o gráfico de configurações de um fragmento no gráfico de navegação, conforme mostrado abaixo:
<?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/list_nav_graph">
<include app:graph="@navigation/list_navigation" />
<include app:graph="@navigation/favorites_navigation" />
<include app:graph="@navigation/settings_navigation" />
<fragment
android:id="@+id/random_fragment"
android:name="com.example.android.RandomFragment"
android:label="@string/fragment_random" >
<!-- Launch into Settings Navigation Graph -->
<action
android:id="@+id/action_random_fragment_to_settings_nav_graph"
app:destination="@id/settings_nav_graph" />
</fragment>
</navigation>
Quando vários módulos de biblioteca precisam referenciar um conjunto comum de
destinos, como um gráfico de login, você não poded incluir esses
destinos comuns no gráfico de navegação de cada módulo de biblioteca. Em vez disso,
adicione esses destinos comuns ao gráfico de navegação do módulo app
.
Cada módulo de biblioteca pode navegar pelos módulos
para ir até esses destinos comuns.
No exemplo anterior, a ação especifica um destino de navegação
de @id/settings_nav_graph
. Esse ID se refere a um destino
definido no gráfico incluído @navigation/settings_navigation.
Navegação de nível superior no módulo do app
O componente de navegação inclui uma classe
NavigationUI
.
Essa classe contém métodos estáticos que gerenciam a navegação com a barra superior
do app, a gaveta de navegação e a navegação inferior. Se os destinos
de nível superior do app forem compostos por elementos da IU fornecidos por módulos
de biblioteca, o módulo app
será um lugar natural para colocar os elementos da IU e
a navegação de nível superior. Como o módulo do app depende dos
módulos da biblioteca colaborativa, todos os destinos são acessíveis
no código definido no módulo do app. Isso significa que você pode usar
NavigationUI
para
associar destinos a itens de menu
se o ID do item corresponder ao ID de um destino.
Na figura 2, o módulo app
de exemplo define uma
BottomNavigationView
na atividade principal. Os IDs de item de menu correspondem aos IDs dos gráficos de navegação
da biblioteca:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@id/list_nav_graph"
android:icon="@drawable/ic_list"
android:title="List"
app:showAsAction="ifRoom"/>
<item
android:id="@id/favorites_nav_graph"
android:icon="@drawable/ic_favorite"
android:title="Favorites"
app:showAsAction="ifRoom"/>
<item
android:id="@id/settings_nav_graph"
android:icon="@drawable/ic_settings"
android:title="Settings"
app:showAsAction="ifRoom" />
</menu>
Para permitir que NavigationUI
gerencie a
navegação inferior, chame
setupWithNavController()
em onCreate()
na sua classe de atividade principal. conforme mostrado no
exemplo a seguir:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment val navController = navHostFragment.navController findViewById<BottomNavigationView>(R.id.bottom_nav) .setupWithNavController(navController) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); NavHostFragment navHostFragment = (NavHostFragment) supportFragmentManager.findFragmentById(R.id.nav_host_fragment); NavController navController = navHostFragment.getNavController(); BottomNavigationView bottomNav = findViewById(R.id.bottom_nav); NavigationUI.setupWithNavController(bottomNav, navController); }
Com esse código, NavigationUI
navegará até o gráfico de
biblioteca adequado quando o usuário clicar em um item de navegação inferior.
Lembre-se de que, geralmente, não é recomendado o módulo do app ter uma dependência forte em um destino específico incorporado profundamente ao gráfico de navegação dos módulos da biblioteca. Na maioria dos casos, convém que o módulo do app saiba somente sobre o ponto de entrada de qualquer gráfico de navegação incorporado ou incluído. Isso também se aplica fora de módulos de biblioteca. Se você precisar criar um link para um destino profundo no gráfico de navegação da biblioteca, a maneira preferencial de fazer isso é usando um link direto. Links diretos também são a única maneira de uma biblioteca navegar para um destino no gráfico de navegação de outra biblioteca.
Como navegar por módulos de biblioteca
Durante a compilação, os módulos de bibliotecas independentes não podem ver uns aos outros, então não é possível usar IDs para navegar para destinos em outros módulos. Em vez disso, use um link direto para navegar diretamente até um destino associado a um link direto implícito.
Continuando com o exemplo anterior, imagine que você precisa navegar de um botão no módulo de lista até um destino aninhado no módulo de configurações. Para fazer isso, adicione um link direto para o destino no gráfico de navegação das configurações, conforme mostrado abaixo:
<?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/settings_nav_graph"
app:startDestination="@id/settings_fragment_one">
...
<fragment
android:id="@+id/settings_fragment_two"
android:name="com.example.google.login.SettingsFragmentTwo"
android:label="@string/settings_fragment_two" >
<deepLink
app:uri="android-app://example.google.app/settings_fragment_two" />
</fragment>
</navigation>
Em seguida, adicione o código a seguir ao onClickListener
do botão no fragmento
da lista:
Kotlin
button.setOnClickListener { val request = NavDeepLinkRequest.Builder .fromUri("android-app://example.google.app/settings_fragment_two".toUri()) .build() findNavController().navigate(request) }
Java
button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { NavDeepLinkRequest request = NavDeepLinkRequest.Builder .fromUri(Uri.parse("android-app://example.google.app/settings_fragment_two")) .build(); NavHostFragment.findNavController(this).navigate(request); } });
Diferentemente da navegação usando IDs de ação ou de destino, você pode navegar para qualquer URI em qualquer gráfico, mesmo entre módulos.
Ao navegar usando URI, a backstack não é redefinida. Esse comportamento é diferente de outras navegações de link direto explícito, em que a backstack é substituída durante a navegação.