0

Use NavArgs<*> para transferir informações entre Fragments

#Kotlin #Android
Francisco Rasia
Francisco Rasia

Passar informações entre Fragments no Android é mais simples do que parece quando usamos o componente Navigation e o delegate navArgs.

Esse artigo abre uma nova série de publilcações dedicada ao fluxo de dados entre os componentes do App. Hoje vamos explorar uma maneira simples e rápida de se fazer a navegação entre Fragments no Android, passando dados de uma tela para outra no App.


🐱‍👤Go Ninjas!

O trânsito de dados vai empregaro componente Navigation (parte do Android Jetpack) e o plugin safe-args, que garante a segurança de tipo evitando crashes no app. Esse passo-a-passo considera que o app já possui um arquivo de navegação na pasta res/navigation.


1. Importar as dependências

No arquivo build.gradle do nível do projeto:

dependencies {
   def nav_version = "2.3.5"
    classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version")
    }



2. Adicionar o plugin safeargs

Agora, adicione o seguinte plugin ao arquivo build.gradle do nível do app:


plugins {
 id("androidx.navigation.safeargs")
}


3. Adicione argumentos ao fragmento de destino

Fazemos isso no próprio editor gráfico do Android Studio: abra o arquivo XML da pasta res/navigation, escolha um dos destinos e, na aba direita, clique em Attributes e, depois, clique no + da aba Arguments. Preencha os campos da janela de diálogo para definir o tipo de argumento e, se quiser, o seu valor padrão. Detalhe: o dado pode ser tanto um tipo primitivo quanto uma instância de uma classe do app!

4. Escreva método que chama o novo Fragment

Aqui está o primeiro truque ninja: o plugin safeargs gera automaticamente uma classe *FragmentDirections, que tem como atributos as diferentes ações criadas no mapa de navegação (cada flecha no mapa é uma action). Podemos navegar para um destino invocando o NavController e passando a action desejada:


 private fun jogoEncerrado() {
   val action = MainFragmentDirections.actionMainFragmentToGameOverFragment()
   findNavController().navigate(action)
 }


Até aqui, tudo o que fizemos foi indicar o destino da navegação. Para transferirmos a informação é preciso acessar os argumentos da action e atribuir o valor desejado:


private fun jogoEncerrado() {
   val pontos: Int = mGameViewModel.score.value ?: 0 // valor a pegar do ViewModel
   val action = MainFragmentDirections.actionMainFragmentToGameOverFragment()
   action.pontuacao = pontos //atribuído como argumento
   findNavController().navigate(action)
 }


Agora sim! Nossa action está ao mesmo tempo apontando para o Fragment de destino e carregando as informações que desejamos passar.


5. Criar um atributo NavArgs<*> no Fragmento de destino

Vamos adicionar um atributo do tipo NavArgs<*> no fragmento de destino. O plugin safeargs também cria automaticamente uma classe para os argumentos, com o nome *FragmentArgs. No exemplo, o fragmento se chama GameOverFragment e, portanto, a classe de argumentos será GameOverFragmentArgs:


private val argumentos by navArgs<GameOverFragmentArgs>()


E pronto! Agora os dados recebidos estão disponíveis como atributos do objeto argumentos. Use sem moderação.


🛸 Um exemplo prático

É mais fácil entender todos esses passos com um exemplo prático. Vou utilizar como exemplo o app Anagrama. Você pode baixar o projeto no meu repositório ou seguir o passo-a-passo em qualquer projeto seu que utilize Fragments e ViewModels.

💻 Repositório no github: https://github.com/chicorasia/anagrama

Use o commit c6aaf3d e a branch navigation_2.

Confira o passo-a-passo no vídeo: 💊 Passando informações entre Fragments com navArgs no Android com Kotlin - https://youtu.be/rSMpTz2RqZU


🎯 Conclusão

Nesse artigo nós vimos como passar informações entre Fragments usando as facilidades do componente Navigation no Android com Kotlin.


📃Para saber mais

Primeiros passos com o componente Navigation - Documentação


📷

Photo by Oskar Kadaksoo on Unsplash

0
6

Comentários (2)

0
Luis Maior

Luis Maior

09/08/2021 17:37

Só corrigindo:


Ali no

val action = MainFragmentDirections.actionMainFragmentToGameOverFragment()

o(s) atributo(s) devem ser passados por parâmetro, ficando dessa forma:

val action = MainFragmentDirections.actionMainFragmentToGameOverFragment(pontos)

Não sendo mais necessário essa linha:

action.pontuacao = pontos


0
Isaias Bueno

Isaias Bueno

25/05/2021 09:59

Muito obrigado pelo excelente artigo e conteúdo!

Arquiteto, urbanista, desenvolvedor Java & Android e criador em chefe na chicorialabs.com.br

Brasil