Como usar o Jetpack Navigation em projetos multi módulos

Compartilhe

Compartilhar no facebook
Compartilhar no google
Compartilhar no twitter
Compartilhar no linkedin

Neste artigo, mostrarei como utilizar o Navigation, em um projeto modularizado.

O Navigation é um componente que faz parte do Jetpack.

O Navigation consiste de três partes principais:

  • NavGraph: é um XML que centraliza as informações de navegação de uma feature.
  • NavHost: é um contêiner vazio que mostra destinos do gráfico de navegação. O componente de navegação contém uma implementação NavHostpadrão, NavHostFragment, que mostra os destinos do fragmento.
  • NavController: é um objeto que gerencia a navegação do aplicativo em um NavHost. O NavController organiza a troca do conteúdo de destino no NavHost conforme os usuários se movem pelo aplicativo.

Texto completo aqui .

Porque utilizar o Navigation ?

Com o Navigation é possível ver todo a navegação através do NavGraph , não sendo necessário assim procurar por cada Intent e FragmentTransaction no projeto e para encontrar todos os destinos possíveis.

Não é mais necessário se preocupar com o fato de o botão de voltar sair do aplicativo ao vir de um deep link e falar de deep link, eles também têm essa informação da navegação.

Segurança ao passar argumentos utilizando o SafeArgs . Não é mais necessário fazer verificações e proteções de segurança, porque é possível ter os argumentos com tipos definidos.

Ele também funciona com os padrões atuais da interface do usuário de navegação, como [bottom nav] (https://material.io/components/bottom-navigation), com apenas algumas configurações e pode lidar com transições e animações 💙 entre a navegação.

 

Pré requisitos

Para utilizar o Navigation é necessário ter instalado o Android Studio na versão 3.3 ou superior.

E adicionar no build.gradle do projeto as dependências do navigation:

implementation "androidx.navigation:navigation-fragment-ktx:2.2.2"
implementation "androidx.navigation:navigation-ui-ktx:2.2.2"

view raw
build.gradle
hosted with ❤ by GitHub

[^]: No momento da criação deste artigo a versão mais recente é a 2.2.2

Em projetos monolitos temos todas as features e camadas em um único módulo, mas nem todas features precisam uma das outras, isso também se aplica a navegação.

Hands On

Como exemplo temos uma feature 1 que tem 2 fragments e faz a navegação de Fragment A -> Fragment B

Utilizando o navigation, precisaremos apenas de um NavGraphcom nossos 2 destinos, e um action que leva do Fragment A ao Fragment B

<?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_feature_one"
app:startDestination="@id/fragment_a">
<fragment
android:id="@+id/fragment_a"
android:name="io.jgabriel.featureone.FragmentA">
<action
android:id="@+id/action_go_to_b"
app:destination="@+id/fragment_b"
app:popUpTo="@+id/fragment_a" />
</fragment>
<fragment
android:id="@+id/fragment_b"
android:name="io.jgabriel.featureone.FragmentB"/>
</navigation>

view raw
navgraph.xml
hosted with ❤ by GitHub

Assim temos a navegação da nossa primeira feature.

Agora iremos aumentar a nossa aplição incluindo mais 2 feature modules :

Nossa aplicação agora contém essas features e fragments :

Será necessário também adicionar os NavGraphspara as novas features criadas seguindo o mesmo modelo da Feature 1

<?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_feature_two"
app:startDestination="@id/fragment_c">
<fragment
android:id="@+id/fragment_c"
android:name="io.jgabriel.featuretwo.FragmentC">
<action
android:id="@+id/action_go_to_d"
app:destination="@+id/fragment_d"
app:popUpTo="@+id/fragment_c" />
</fragment>
<fragment
android:id="@+id/fragment_d"
android:name="io.jgabriel.featuretwo.FragmentD"/>
</navigation>

view raw
navgraph_2.xml
hosted with ❤ by GitHub

 

<?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_feature_three"
app:startDestination="@id/fragment_e">
<fragment
android:id="@+id/fragment_e"
android:name="io.jgabriel.featurethree.FragmentE">
<action
android:id="@+id/action_go_to_f"
app:destination="@+id/fragment_f"
app:popUpTo="@+id/fragment_e" />
</fragment>
<fragment
android:id="@+id/fragment_f"
android:name="io.jgabriel.featurethree.FragmentF" />
</navigation>

view raw
navgraph_3.xml
hosted with ❤ by GitHub

os adicionar as nossas feature ao módulo de aplicação através do build.gradle

implementation project(":featureone")
implementation project(":featuretwo")
implementation project(":featurethree")

view raw
build.gradle
hosted with ❤ by GitHub

Agora o nosso módulo de aplicação conhece as nossas 3 features.

Para não precisar repetir toda a navegação feita em cada feature, vamos reutilizar os NavGraphs, através da tag de include dentro do NavGraph do nosso módulo e aplicação

<?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"
android:id="@+id/nav_main"
app:startDestination="@id/nav_feature_one">
<include app:graph="@navigation/nav_feature_one" />
<include app:graph="@navigation/nav_feature_two" />
<include app:graph="@navigation/nav_feature_three" />
</navigation>

view raw
app_nav_graph.xml
hosted with ❤ by GitHub

 

Agora já é possível fazer a navegação de qualquer fragment dentro do módulo de aplicação.

Em problemas reais, geralmente precisamos acessar um fragment de uma feature, através de outra por exemplo:

O Fragment B que está na Feature 1, precisa navegar até Fragment D que está na Feature 2 :

Para isso vamos adicionar deep links aos fragments e fazer a navegação através deles, assim as features continuarão independentes e o módulo de app será o responsável por gerenciar essa navegação.

NavGraph Feature Two

Utilizando a tag deepLink, podemos especificar o URI que podemos usar para navegar para esse destino específico, sem a

Feature One precisar conhecer a nossa Feature Two.

Para fazer essa navegação vamos adicionar um click no FragmentB que vai navegar até o FragmentD

class FragmentB : Fragment() {
fun onViewCreated(…) {
view.setOnClickListener {
val uri = Uri.parse("myApp://fragmentD")
findNavController().navigate(uri)
}
}
}

view raw
FragmentB.kt
hosted with ❤ by GitHub

E com isso mantemos os nossos módulos independentes um dos outros mas capazes de navegarem entre si.

Obrigado por ler até aqui todo o código utilizado está disponível no meu Git .

 

Outros artigos que podem ser interessantes para você:

Camila Monteiro

Camila Monteiro

Graduada em Marketing pela Universidade de São Paulo e Analista de Employer Branding na Movile. Acredita que as relações humanas e a conexão entre pessoas são capazes de transformar o mundo. Apaixonada por café, plantas e guardar objetos completamente desnecessários.

Deixe um comentário

Categorias

Posts relacionados

Siga-nos

Baixe nosso e-book!

%d blogueiros gostam disto: