Fundamentos de Android em Kotlin 03.2: Definindo caminhos de navegação

No tutorial anterior, você modificou o aplicativo AndroidTrivia para adicionar um fragmento a uma atividade existente. Neste tutorial, você adiciona navegação ao aplicativo.

Introdução à navegação

Estruturando a experiência de navegação do usuário por um aplicativo sempre foi um tópico interessante para desenvolvedores. Para aplicativos Android, o Componente de arquitetura de navegação torna mais fácil implementar a navegação.

Um destino é qualquer lugar dentro do aplicativo para o qual um usuário pode navegar. Um grafo de navegação para um aplicativo consiste em um conjunto de destinos dentro do aplicativo. Os grafos de navegação permitem que você defina visualmente e personalize como os usuários navegam entre os destinos em seu aplicativo.

O que você já deveria saber

O que aprenderá

O que fará

O aplicativo AndroidTrivia, no qual você começou a trabalhar no tutorial anterior, é um jogo no qual os usuários respondem a perguntas sobre o desenvolvimento do Android. Se o usuário responder a três perguntas corretamente, ele ganha o jogo.

Se você concluiu o tutorial anterior, use esse código como o código inicial para este tutorial. Caso contrário, baixe o aplicativo AndroidTriviaFragment do GitHub para obter o código inicial.

Neste tutorial, você atualiza o aplicativo AndroidTrivia das seguintes maneiras:

Etapa 1: Adicione dependências de navegação

Para usar a biblioteca de navegação, você precisa adicionar as dependências de navegação aos seus arquivos Gradle.

  1. Se você ainda não possui sua própria cópia do aplicativo AndroidTrivia do tutorial anterior, baixe o arquivo AndroidTriviaFragment. Abra o aplicativo AndroidTrivia no Android Studio.
  2. No painel Project: Android, abra a pasta Gradle Scripts. Clique duas vezes no arquivo build.gradle do nível do projeto para abrir o arquivo.
  3. No topo do arquivo build.gradle de nível de projeto, junto com as outras variáveis ​​ext, adicione uma variável para navigationVersion. Para encontrar o número da versão de navegação mais recente, consulte Declarando dependências na documentação do desenvolvedor Android.
ext {
        ...
        navigationVersion = '1.0.0-rc02'
        ...
    }
  1. Na pasta Gradle Scripts, abra o arquivo build.gradle de nível de módulo. Adicione as dependências para navigation-fragment-ktx e navigation-ui-ktx, conforme mostrado abaixo:
dependencies {
  ...
  implementation"android.arch.navigation:navigation-fragment-ktx:$navigationVersion"
  implementation "android.arch.navigation:navigation-ui-ktx:$navigationVersion"
  ...
}
  1. Reconstrua o projeto.

Etapa 2: Adicione um grafo de navegação ao projeto

  1. No painel Project: Android, clique com o botão direito na pasta res e selecione New > Android Resource File.
  2. Na caixa de diálogo New Resource File, selecione Navigation como o Resource type.
  3. No campo File name, nomeie o arquivo como navigation.
  4. Certifique-se de que a caixa Chosen qualifiers esteja vazia e clique em OK. Um novo arquivo, navigation.xml, aparece na pasta res > navigation.
  5. Abra o arquivo res > navigation > navigation.xml e clique na guia Design para abrir o Editor de navegação. Observe a mensagem No NavHostFragments found no editor de layout. Você corrige esse problema na próxima tarefa.

Um fragmento de host de navegação atua como um host para os fragmentos em um grafo de navegação. O fragmento do host de navegação geralmente é denominado NavHostFragment.

Conforme o usuário se move entre os destinos definidos no grafo de navegação, o fragmento do host de navegação troca os fragmentos dentro e fora conforme necessário. O fragmento também cria e gerencia a pilha de retorno do fragmento apropriada.

Nesta tarefa, você modifica seu código para substituir o TitleFragment pelo NavHostFragment.

  1. Abra res > layout > activity_main.xml e clique na guia Text.
  2. No arquivo activity_main.xml, altere o nome do fragmento principal existente para androidx.navigation.fragment.NavHostFragment.
  3. Altere o ID para myNavHostFragment.
  4. O fragmento do host de navegação precisa saber qual recurso de grafo de navegação usar. Adicione o atributo app:navGraph e defina-o para o recurso de grafo de navegação, que é @navigation/navigation.
  5. Adicione o atributo app:defaultNavHost e defina-o como "true". Agora, este host de navegação é o host padrão e interceptará o botão Voltar do sistema.

Dentro do arquivo de layout activity_main.xml, seu fragment agora se parece com o seguinte:

            <fragment
                android:id="@+id/myNavHostFragment"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:navGraph="@navigation/navigation"
                app:defaultNavHost="true" />

Nesta tarefa, você adiciona o fragmento do título e o fragmento do jogo ao grafo de navegação do aplicativo. Você conecta os fragmentos uns aos outros. Em seguida, você adiciona um tratador de cliques ao botão Play para que o usuário possa navegar da tela principal para a tela do jogo.

Etapa 1: Adicione dois fragmentos ao grafo de navegação e conecte-os com uma ação

  1. Abra navigation.xml na pasta de recursos navigation. No Editor de navegação, clique no botão New Destination . Uma lista de fragmentos e atividades é exibida.

  2. Selecione fragment_title. Você adiciona fragment_title primeiro, pois o fragmento TitleFragment é onde os usuários do aplicativo começam quando abrem o aplicativo pela primeira vez.


  3. Use o botão New Destination para adicionar o GameFragment.

    Se a prévia mostrar a mensagem "Preview Unavailable", clique no botão Text guia para abrir o XML de navegação. Certifique-se de que o elemento fragment para o gameFragment inclui tools:layout="@layout/fragment_game", conforme mostrado abaixo.
<fragment
   android:id="@+id/gameFragment"
   android:name="com.example.android.navigation.GameFragment"
   android:label="GameFragment"
   tools:layout="@layout/fragment_game" />
  1. No editor de layout, arraste o fragmento do jogo para a direita para que não se sobreponha ao fragmento do título.

  1. Na prévia, mantenha o ponteiro do mouse sobre o fragmento do título. Um ponto de conexão circular aparece no lado direito da vista do fragmento. Clique no ponto de conexão e arraste-o para a prévia do fragmento do jogo. Uma ação é criada para conectar os dois fragmentos.
  2. Para ver os atributos da ação, clique na linha que conecta os dois fragmentos. No painel Attributes, verifique se o ID da ação está definido como action_titleFragment_to_gameFragment.

Etapa 2: Adicione um gerenciador de cliques ao botão Play

O fragmento do título é conectado ao fragmento do jogo por uma ação. Agora você deseja que o botão Play na tela principal conduza o usuário à tela do jogo.

  1. No Android Studio, abra o arquivo TitleFragment.kt. Dentro do método onCreateView(), adicione o seguinte código antes da instrução return:
binding.playButton.setOnClickListener{}
  1. Dentro de setOnClickListener, adicione o código para acessar o botão Play por meio da classe de vinculação e navegue até o fragmento do jogo:
//The complete onClickListener with Navigation
binding.playButton.setOnClickListener { view : View ->
       view.findNavController().navigate(R.id.action_titleFragment_to_gameFragment)
}
  1. Crie o aplicativo e certifique-se de que ele tenha todas as importações de que precisa. Por exemplo, pode ser necessário adicionar a seguinte linha ao arquivo TitleFragment.kt:
import androidx.navigation.findNavController
  1. Execute o aplicativo e toque no botão Play na tela principal. A tela do jogo é aberta.

Nesta etapa, você adiciona navegação condicional, que é a navegação disponível apenas para o usuário em determinados contextos. Um caso de uso comum para navegação condicional é quando um aplicativo tem um fluxo diferente, dependendo se o usuário está conectado.

Seu aplicativo é um caso diferente: Seu aplicativo navegará para um fragmento diferente, com base no fato de o usuário responder a todas as perguntas corretamente.

O código inicial contém dois fragmentos para você usar em sua navegação condicional:

Etapa 1: Adicione GameWonFragment e GameOverFragment ao grafo de navegação

  1. Abra o arquivo navigation.xml, que está na pasta navigation.
  2. Para adicionar o fragmento de game over ao grafo de navegação, clique no botão New Destination no Editor de navegação e selecione fragment_game_over.
  3. Na área de pré-visualização do editor de layout, arraste o fragmento de game over para a direita do fragmento de jogo para que os dois não se sobreponham. Certifique-se de alterar o atributo ID do fragmento de final de jogo para gameOverFragment.
  4. Para adicionar o fragmento ganho pelo jogo ao grafo de navegação, clique no botão New Destination e selecione fragment_game_won.

  5. Arraste o fragmento de jogo vencido abaixo do fragmento de final de jogo para que os dois não se sobreponham. Certifique-se de nomear o atributo ID do fragmento ganho pelo jogo como gameWonFragment.

O editor de layout agora se parece com a seguinte captura de tela:

Etapa 2: Conecte o fragmento do jogo ao fragmento do resultado do jogo

Nesta etapa, você conecta o fragmento de jogo ao fragmento de jogo vencido e ao fragmento de jogo terminado.

  1. Na área de pré-visualização do editor de layout, mantenha o ponteiro do mouse sobre o fragmento do jogo até que o ponto de conexão circular apareça.
  2. Clique no ponto de conexão e arraste-o para o fragmento de final de jogo. Uma linha de conexão azul aparece, representando uma ação que agora conecta o fragmento de jogo ao fragmento de final de jogo.
  3. Da mesma forma, crie uma ação que conecte o fragmento do jogo ao fragmento do jogo ganho. O editor de layout agora se parece com a seguinte captura de tela:
  4. Na prévia, mantenha o ponteiro sobre a linha que conecta o fragmento do jogo ao fragmento ganho pelo jogo. Observe que o ID da ação foi atribuído automaticamente.

Etapa 3: Adicione o código para navegar de um fragmento para o próximo

GameFragment é uma classe de fragmento que contém perguntas e respostas para o jogo. A classe também inclui lógica que determina se o usuário ganha ou perde o jogo. Você precisa adicionar navegação condicional na classe GameFragment, dependendo se o jogador ganha ou perde.

  1. Abra o arquivo GameFragment.kt. O método onCreateView() define uma condição if / else que determina se o jogador ganhou ou perdeu:
binding.submitButton.setOnClickListener @Suppress("UNUSED_ANONYMOUS_PARAMETER")
        { 
              ...
                if (answers[answerIndex] == currentQuestion.answers[0]) {
                    questionIndex++
                    if (questionIndex < numQuestions) {
                        currentQuestion = questions[questionIndex]
                        setQuestion()
                        binding.invalidateAll()
                    } else {
                    }
                } else {
                }
            }
        }
  1. Dentro da condição else para ganhar o jogo, adicione o seguinte código, que navega para o gameWonFragment. Certifique-se de que o nome da ação (action_gameFragment_to_gameWonFragment neste exemplo) corresponda exatamente ao que está definido no arquivo navigation.xml.

view.findNavController()
   .navigate(R.id.action_gameFragment_to_gameWonFragment)
  1. Dentro da condição else para perder o jogo, adicione o seguinte código, que navega para o gameOverFragment:
view.findNavController().
   navigate(R.id.action_gameFragment_to_gameOverFragment)
  1. Execute o aplicativo e jogue respondendo às perguntas. Se você responder todas as três perguntas corretamente, o aplicativo navegará para o GameWonFragment.



    Se você errar alguma dúvida, o aplicativo navegará imediatamente para o GameOverFragment.

O botão Voltar do sistema Android é mostrado como 1 na imagem acima. Se o usuário pressionar o botão Voltar no fragmento do jogo vencido ou no fragmento do jogo terminado, o aplicativo navegará para a tela da pergunta. Idealmente, o botão Voltar deve navegar de volta para a tela principal do aplicativo. Você altera o destino do botão Voltar na próxima tarefa.

O sistema Android mantém o controle de onde os usuários navegam em um dispositivo com Android. Cada vez que o usuário vai para um novo destino no dispositivo, o Android adiciona esse destino à pilha de retorno.

Quando o usuário pressiona o botão Voltar, o aplicativo vai para o destino que está no topo da pilha de retorno. Por padrão, o topo da pilha de retorno é a tela que o usuário visualizou pela última vez. O botão Voltar é normalmente o botão mais à esquerda na parte inferior da tela, conforme mostrado abaixo. (A aparência exata do botão Voltar é diferente em dispositivos diferentes).

Até agora, você deixou o controlador de navegação tratar com a pilha de retorno. Quando o usuário navega para um destino em seu aplicativo, o Android adiciona esse destino à pilha de retorno.

No aplicativo AndroidTrivia, quando o usuário pressiona o botão Voltar na tela GameOverFragment ou GameWonFragment, eles voltam para a tela GameFragment. Mas você não quer enviar o usuário para o GameFragment, pois o jogo acabou. O usuário poderia reiniciar o jogo, mas uma experiência melhor seria voltar para a tela principal.

Uma ação de navegação pode modificar a pilha de retorno. Nesta tarefa, você altera a ação que navega do fragmento do jogo de forma que a ação remova o GameFragment da pilha de retorno. Quando o usuário ganha ou perde o jogo, se pressionar o botão Voltar, o aplicativo pula o GameFragment e volta para o TitleFragment.

Etapa 1: Defina o comportamento de desempilhamento para as ações de navegação

Nesta etapa, você gerencia a pilha de retorno para que, quando o usuário estiver na tela GameWon ou GameOver, pressionar o botão Voltar retorne-o à tela principal. Você gerencia a pilha de retorno definindo o comportamento de "desempilhamento" para as ações que conectam os fragmentos:

Nesta etapa, você define o atributo popUpTo para as duas ações criadas na tarefa anterior. Você faz isso usando o campo Pop To no painel Attributes do editor de layout.

  1. Abra navigation.xml na pasta res > navigation. Se o grafo de navegação não aparecer no editor de layout, clique na guia Design.
  2. Selecione a ação para navegar de gameFragment para gameOverFragment. (Na área de pré-visualização, a ação é representada por uma linha azul que conecta os dois fragmentos).
  3. No painel Attributes, defina Pop To como gameFragment. Selecione a caixa de seleção Inclusive.


    Isso define os atributos popUpTo e popUpToInclusive no XML. Os atributos dizem ao componente de navegação para remover fragmentos da pilha de retorno até e incluindo GameFragment. (Isso tem o mesmo efeito que definir o campo Pop To como titleFragment e desmarcar a caixa de seleção Inclusive).
  4. Selecione a ação para navegar do gameFragment para o gameWonFragment. Novamente, defina Pop To para gameFragment no painel Attributes e selecione a caixa de seleção Inclusive.

  5. Execute o aplicativo, jogue o jogo e pressione o botão Voltar. Quer você ganhe ou perca, o botão Voltar o leva de volta ao TitleFragment.

Etapa 2: Adicione mais ações de navegação e adicionar tratadores onClick

Atualmente, seu aplicativo tem o seguinte fluxo de usuário:

Nesta etapa, você implementa mais duas etapas do fluxo do usuário:

Para criar este fluxo de usuário, use o atributo PopUpTo para gerenciar a pilha de retorno:

  1. Dentro do arquivo navigation.xml, adicione uma ação de navegação conectando gameOverFragment a gameFragment. Certifique-se de que os nomes dos fragmentos no ID da ação correspondam aos nomes dos fragmentos que estão no XML. Por exemplo, o ID da ação pode ser action_gameOverFragment_to_gameFragment.

  2. No painel Attributes, defina o atributo Pop To da ação como titleFragment.
  3. Desmarque a caixa de seleção Inclusive, pois você não deseja que o titleFragment seja incluído nos destinos que são removidos da pilha de retorno. Em vez disso, você deseja que tudo até o TitleFragment (mas sem incluí-lo) seja removido da pilha de retorno.

  4. Dentro do arquivo navigation.xml, adicione uma ação de navegação conectando gameWonFragment a gameFragment.

  5. Para a ação que você acabou de criar, defina o atributo Pop To como titleFragment e desmarque a caixa de seleção Inclusive.

Agora adicione funcionalidade aos botões Try Again e Next Match. Quando o usuário toca em um dos botões, você deseja que o aplicativo navegue até a tela GameFragment para que o usuário possa tentar o jogo novamente.

  1. Abra o arquivo GameOverFragment.kt Kotlin. No final do método onCreateView(), antes da instrução return, adicione o código a seguir. O código adiciona um ouvinte de clique ao botão Try Again. Quando o usuário toca no botão, o aplicativo navega para o fragmento do jogo.

        binding.tryAgainButton.setOnClickListener{view: View->
        view.findNavController()
                .navigate(R.id.action_gameOverFragment_to_gameFragment)}
  1. Abra o arquivo GameWonFragment.kt Kotlin. No final do método onCreateView(), antes da instrução return, adicione o seguinte código:

        binding.nextMatchButton.setOnClickListener{view: View->
            view.findNavController()
                    .navigate(R.id.action_gameWonFragment_to_gameFragment)}
  1. Execute seu aplicativo, jogue o jogo e teste os botões Next Match e Try Again. Ambos os botões devem levá-lo de volta à tela do jogo para que você possa tentar novamente.
  2. Depois de ganhar ou perder o jogo, toque em Next Match ou Try Again. Agora pressione o botão Voltar do sistema. O aplicativo deve navegar para a tela principal, em vez de voltar para a tela de onde você acabou de sair.

A barra de aplicativos

A barra de aplicativos, às vezes chamada de barra de ação, é um espaço dedicado para a marca e identidade do aplicativo. Por exemplo, você pode definir a cor da barra de aplicativos. A barra de aplicativos fornece ao usuário acesso a recursos de navegação familiares, como um menu de opções. Para acessar o menu de opções na barra de aplicativos, o usuário toca no ícone com os três pontos verticais .

A barra de aplicativos exibe uma sequência principal que pode ser alterada a cada tela. Para a tela principal do aplicativo AndroidTrivia, a barra de aplicativos exibe "Android Trivia". Na tela da pergunta, a string do título também mostra em qual pergunta o usuário está ("1/3", "2/3" ou "3/3")

O botão Acima

Atualmente em seu aplicativo, o usuário usa o botão Voltar do sistema para navegar para as telas anteriores. No entanto, os aplicativos Android também podem ter um botão Acima na tela que aparece no canto superior esquerdo da barra de aplicativos.

No aplicativo AndroidTrivia, você deseja que o botão Acima apareça em todas as telas, exceto na tela principal. O botão Acima deve desaparecer quando o usuário chegar à tela principal, pois a tela principal está no topo da hierarquia de telas do aplicativo.

Adicionando suporte para um botão Acima

Os componentes de navegação incluem uma biblioteca de IU chamada NavigationUI. O controlador de navegação se integra à barra de aplicativos para implementar o comportamento do botão Acima, para que você não precise fazer isso sozinho.

Nas etapas a seguir, você usa o controlador de navegação para adicionar um botão Acima ao seu aplicativo:

  1. Abra o arquivo MainActivity.kt kotlin. Dentro do método onCreate(), adicione o código para encontrar o objeto controlador de navegação:
val navController = this.findNavController(R.id.myNavHostFragment)
  1. Também dentro do método onCreate(), adicione o código para vincular o controlador de navegação à barra do aplicativo:
NavigationUI.setupActionBarWithNavController(this,navController)
  1. Após o método onCreate(), substitua o método onSupportNavigateUp() para chamar navigateUp() no controlador de navegação:
override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.myNavHostFragment)
        return navController.navigateUp()
    }
  1. Execute o aplicativo. O botão Acima aparece na barra de aplicativos em todas as telas, exceto na tela principal. Não importa onde você esteja no aplicativo, tocar no botão Acima leva você para a tela principal.

O Android tem diferentes tipos de menus, incluindo o menu de opções. Em dispositivos Android modernos, o usuário acessa o menu de opções tocando em três pontos verticais que aparecem na barra de aplicativos.

Nesta tarefa, você adiciona um item de menu About ao menu de opções. Quando o usuário toca no item de menu About, o aplicativo navega para o AboutFragment e o usuário vê informações sobre como usar o aplicativo.

Etapa 1: Adicione o AboutFragment ao grafo de navegação

  1. >>>Abra o arquivo navigation.xml e clique na guia Design para ver o grafo de navegação.
  2. Clique no botão New Destination e selecione fragment_about.
  3. No editor de layout, arraste o fragmento "about" para a esquerda para que não se sobreponha aos outros fragmentos. Certifique-se de que o ID do fragmento seja aboutFragment.

Etapa 2: Adicione o recurso do menu de opções

  1. No painel Android Studio Project, clique com o botão direito na pasta res e selecione New > Android Resource File.
  2. Na caixa de diálogo New Resource File, nomeie o arquivo como options_menu.
  3. Selecione Menu como o Resource type e clique em OK.
  1. Abra o arquivo options_menu.xml da pasta res > menu e clique na guia Design para ver o editor de layout.
  2. No painel Palette, arraste um Menu Item (mostrado como 1 na imagem abaixo) e solte-o em qualquer lugar no painel do editor de design (2). Um item de menu aparece na prévia (3) e na Component Tree (4).
  3. Na prévia ou na Component Tree, clique no item de menu para mostrar seus atributos no painel Attributes.
  4. Defina o ID do item de menu como aboutFragment. Defina o título para @string/about.

Etapa 3: Adicione um gerenciador onClick

Nesta etapa, você adiciona código para implementar o comportamento quando o usuário toca no item de menu About.

  1. Abra o arquivo TitleFragment.kt Kotlin. Dentro do método onCreateView(), antes do return, chame o método setHasOptionsMenu() e passe true.
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                         savedInstanceState: Bundle?): View? {
   ...
   setHasOptionsMenu(true)
   return binding.root
}
  1. Após o método onCreateView(), substitua o método onCreateOptionsMenu(). No método, adicione o menu de opções e infle o arquivo de recursos do menu.
override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
   super.onCreateOptionsMenu(menu, inflater)
   inflater?.inflate(R.menu.options_menu, menu)
}
  1. Substitua o método onOptionsItemSelected() para executar a ação apropriada quando o item de menu for tocado. Nesse caso, a ação é navegar até o fragmento que possui o mesmo id do item de menu selecionado.
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
   return NavigationUI.onNavDestinationSelected(item!!,
           view!!.findNavController())
           || super.onOptionsItemSelected(item)
}
  1. Se o aplicativo não for construído, verifique se você precisa importar pacotes para corrigir referências não resolvidas no código. Por exemplo, você pode adicionar import android.view.* para resolver várias referências (e substituir importações mais específicas, como import android.view.ViewGroup).
  2. Execute o aplicativo e teste o item de menu About que está no menu de opções. Quando você toca no item de menu, o aplicativo deve navegar até a tela "sobre".


Nesta tarefa, você adiciona uma gaveta de navegação ao aplicativo AndroidTrivia. A gaveta de navegação é um painel que desliza para fora da borda da tela. A gaveta normalmente contém um cabeçalho e um menu.

Em dispositivos do tamanho de um telefone, a gaveta de navegação fica oculta quando não está em uso. Dois tipos de ações do usuário podem fazer a gaveta de navegação aparecer:

A captura de tela abaixo mostra uma gaveta de navegação aberta.

A gaveta de navegação faz parte da biblioteca de Componentes de materiais para Android ou biblioteca de materiais. Você usa a biblioteca de materiais para implementar padrões que fazem parte das diretrizes de Material Design do Google.

Em seu aplicativo AndroidTrivia, a gaveta de navegação conterá dois itens de menu. O primeiro item aponta para o fragmento "about" existente e o segundo item aponta para um novo fragmento de "regras".

Etapa 1: Adicione a biblioteca de materiais ao seu projeto

  1. No arquivo de compilação do Gradle no nível do aplicativo, adicione a dependência para a biblioteca de materiais:
dependencies {
    ...
    implementation "com.google.android.material:material:$supportlibVersion"
    ...
}
  1. Sincronize seu projeto.

Etapa 2: Certifique-se de que os fragmentos de destino tenham IDs

A gaveta de navegação terá dois itens de menu, cada um representando um fragmento que pode ser alcançado a partir da gaveta de navegação. Ambos os destinos devem ter um ID no grafo de navegação.

O AboutFragment já tem um ID no gráfico de navegação, mas o RulesFragment não, então adicione-o agora:

  1. Abra o arquivo de layout fragment_rules.xml para ver como ele se parece. Clique na guia Design para ver a prévia no editor de design.
  2. Abra o arquivo navigation.xml no Navigation Editor. Clique no botão New Destination e adicione o fragmento de regras. Defina seu ID para rulesFragment.



Etapa 3: Crie o menu da gaveta e o layout da gaveta

Para criar uma gaveta de navegação, você cria o menu de navegação. Você também precisa colocar suas vistas dentro de um DrawerLayout no arquivo de layout.

  1. Crie o menu para a gaveta. No painel Projeto, clique com o botão direito na pasta res e selecione New Resource File. Nomeie o arquivo navdrawer_menu, defina o tipo de recurso para Menu e clique em OK.
  2. Abra navdrawer_menu.xml na pasta res > menu e clique na guia Design. Adicione dois itens de menu arrastando-os do painel Palette para o painel Component Tree.
  3. Para o primeiro item de menu, defina id como rulesFragment.(O ID de um item de menu deve ser o mesmo que o ID do fragmento). Defina o title como @string/rules e o icon para @drawable/rules.

  4. Para o segundo item de menu, defina o id para aboutFragment, a string title para @string/about, e o ícone para @drawable/about_android_trivia.

  1. Abra o arquivo de layout activity_main.xml. Para obter todas as funcionalidades de gaveta gratuitamente, coloque suas vistas dentro de um DrawerLayout. Envolva todo o <LinearLayout> dentro de um <DrawerLayout>. (Em outras palavras, adicione um DrawerLayout como a vista raiz).
<layout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto">
   <androidx.drawerlayout.widget.DrawerLayout
       android:id="@+id/drawerLayout"
       android:layout_width="match_parent"
       android:layout_height="match_parent">

   <LinearLayout
       . . . 
       </LinearLayout>
   </androidx.drawerlayout.widget.DrawerLayout>
</layout>
  1. Agora adicione a gaveta, que é uma NavigationView que usa o navdrawer_menu que você acabou de definir. Adicione o seguinte código no DrawerLayout, após o elemento </LinearLayout>:
<com.google.android.material.navigation.NavigationView
   android:id="@+id/navView"
   android:layout_width="wrap_content"
   android:layout_height="match_parent"
   android:layout_gravity="start"
   app:headerLayout="@layout/nav_header"
   app:menu="@menu/navdrawer_menu" />

Etapa 4: Exiba a gaveta de navegação

Você criou os itens de menu para a gaveta de navegação e o layout da gaveta de navegação. Agora você precisa conectar a gaveta de navegação ao controlador de navegação para que, quando os usuários selecionarem itens na gaveta de navegação, o aplicativo navegue até o fragmento apropriado.

  1. Abra o arquivo Mainactivity.kt Kotlin. Em onCreate(), adicione o código que permite ao usuário exibir a gaveta de navegação. Faça isso chamando setupWithNavController(). Adicione o seguinte código na parte inferior de onCreate():
NavigationUI.setupWithNavController(binding.navView, navController)
  1. Execute seu aplicativo. Deslize da borda esquerda para exibir a gaveta de navegação e certifique-se de que cada um dos itens de menu na gaveta vá para o lugar certo.

Embora a gaveta de navegação funcione, você precisa consertar mais um aspecto. Normalmente, os aplicativos também permitem que os usuários exibam a gaveta de navegação tocando no botão da gaveta (três linhas) na barra de aplicativos da tela inicial. Seu aplicativo ainda não exibe o botão da gaveta na tela inicial.

Etapa 5: Exiba a gaveta de navegação no botão da gaveta

A etapa final é permitir que o usuário acesse a gaveta de navegação a partir do botão da gaveta no canto superior esquerdo da barra do aplicativo.

  1. No arquivo Mainactivity.kt Kotlin, adicione a variável de membro lateinit drawerLayout para representar o layout da gaveta:
    private lateinit var drawerLayout: DrawerLayout
  1. Dentro do método onCreate(), inicialize drawerLayout, após a variável binding ter sido inicializada.
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this,
                R.layout.activity_main)

drawerLayout = binding.drawerLayout
  1. Adicione o drawerLayout como o terceiro parâmetro para o método setupActionBarWithNavController():
NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
  1. Edite o método onSupportNavigateUp() para retornar NavigationUI.navigateUp em vez de retornar navController.navigateUp. Passe o controlador de navegação e o layout da gaveta para navigateUp(). O método será parecido com o seguinte:
override fun onSupportNavigateUp(): Boolean {
   val navController = this.findNavController(R.id.myNavHostFragment)
   return NavigationUI.navigateUp(navController, drawerLayout)
}
  1. Pode ser necessário adicionar outra importação ao arquivo para que todas as referências sejam resolvidas, por exemplo:
import androidx.drawerlayout.widget.DrawerLayout
  1. Execute seu aplicativo. Deslize da borda esquerda para exibir a gaveta de navegação e certifique-se de que cada um dos itens de menu na gaveta vá para o lugar certo.
  2. Vá para a tela inicial e toque no botão da gaveta de navegação para garantir que a gaveta de navegação apareça. Certifique-se de que clicar nas opções Rules ou About na gaveta de navegação leva você ao lugar certo.

Parabéns!

Agora você adicionou várias opções de navegação diferentes ao seu aplicativo.

O usuário agora pode progredir no aplicativo jogando. Eles podem voltar para a tela inicial a qualquer momento usando o botão Acima. Eles podem acessar a tela Sobre a partir do menu Options ou da gaveta de navegação. Pressionando o botão Voltar os leva de volta às telas anteriores de uma forma que faça sentido para o aplicativo. O usuário pode abrir a gaveta de navegação deslizando da esquerda para a direita em qualquer tela ou tocando no botão da gaveta na barra de aplicativos da tela inicial.

Seu aplicativo inclui caminhos de navegação robustos e lógicos que são intuitivos para o seu usuário usar. Parabéns!

Projeto Android Studio: AndroidTriviaNavigation

Componentes de navegação

Para usar a biblioteca de navegação do Android, você precisa fazer algumas configurações:

Destinos de navegação são fragmentos, atividades ou outros componentes do aplicativo para os quais o usuário navega. Um grafo de navegação define os caminhos possíveis de um destino de navegação para o próximo.

Um fragmento do host de navegação, geralmente denominado NavHostFragment, atua como um host para os fragmentos no grafo de navegação:

Para definir qual fragmento é exibido quando o usuário toca em uma vista (por exemplo, um botão), defina o ouvinte onClick para a vista:

Navegação condicional navega para uma tela em um caso e para uma tela diferente em outro caso. Para criar navegação condicional:

  1. Use o Editor de Navegação para criar uma conexão do fragmento inicial para cada um dos fragmentos de destino possíveis.
  2. Dê a cada conexão um ID exclusivo.
  3. No método ouvinte de clique da View, adicione o código para detectar as condições. Em seguida, chame findNavController().navigate() na vista, passando o ID para a ação apropriada.

O botão Voltar

O botão Voltar do sistema geralmente fica na parte inferior do dispositivo. Por padrão, o botão Voltar leva o usuário de volta à tela que ele viu mais recentemente. Em algumas situações, você pode controlar para onde o botão Voltar leva o usuário:

O botão Acima

As telas em um aplicativo Android podem ter um botão Acima na tela que aparece no canto superior esquerdo da barra do aplicativo. (Às vezes, a barra do aplicativo é chamada de barra de ação). O botão Acima navega "para cima" nas telas do aplicativo, com base nas relações hierárquicas entre as telas.

A biblioteca NavigationUI do controlador de navegação se integra à barra de aplicativos para permitir que o usuário toque no botão Acima na barra de aplicativos para voltar à tela inicial do aplicativo de qualquer lugar no aplicativo .

Para vincular o controlador de navegação à barra de aplicativos:

  1. Em onCreate(), chame setupActionBarWithNavController() na classe NavigationUI, passando no controlador de navegação:
val navController = this.findNavController(R.id.myNavHostFragment)
NavigationUI.setupActionBarWithNavController(this,navController)
  1. Substitua o método onSupportNavigateUp() para chamar navigateUp() no controlador de navegação:
override fun onSupportNavigateUp(): Boolean {
        val navController = this.findNavController(R.id.myNavHostFragment)
        return navController.navigateUp()
    }
}

O menu de opções

O menu de opções é um menu que o usuário acessa a partir da barra do aplicativo tocando no ícone com os três pontos verticais . Para criar um menu de opções com um item de menu que exibe um fragmento, certifique-se de que o fragmento tenha um ID. Em seguida, defina o menu de opções e codifique o tratador onOptionsItemSelected() para os itens de menu.

1. Certifique-se de que o fragmento tenha um ID:

2. Defina o menu de opções:

3. Codifique o tratador onClick para o item de menu:

override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
   super.onCreateOptionsMenu(menu, inflater)
   inflater?.inflate(R.menu.options_menu, menu)
}
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
   return NavigationUI.onNavDestinationSelected(item!!,
           view!!.findNavController())
           || super.onOptionsItemSelected(item)
}

A gaveta de navegação

A gaveta de navegaçãoé um painel que desliza para fora da borda da tela. Existem duas maneiras de o usuário abrir a gaveta de navegação:

Para adicionar uma gaveta de navegação ao seu aplicativo:

  1. Adicione dependências a build.gradle (app).
  2. Certifique-se de que cada fragmento de destino tenha um ID.
  3. Crie o menu para a gaveta.
  4. Adicione a gaveta ao layout do fragmento.
  5. Conecte a gaveta ao controlador de navegação.
  6. Configure o botão de gaveta na barra de aplicativos.

Essas etapas são explicadas com mais detalhes a seguir.

1. Adicione dependências a build.gradle:

dependencies {
    ...
    implementation "com.google.android.material:material:$supportlibVersion"
    ...
}

2. Provenha a cada fragmento de destino uma ID:

3. Crie o menu para a gaveta:

4. Adicione a gaveta ao layout do fragmento:

5. Conecte a gaveta ao controlador de navegação:

val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
       this, R.layout.activity_main)
NavigationUI.setupWithNavController(binding.navView, navController)

6. Configure o botão de gaveta na barra de aplicativos:

val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
    this, R.layout.activity_main)

NavigationUI.setupActionBarWithNavController(
    this, navController, binding.drawerLayout)
override fun onSupportNavigateUp(): Boolean {
   val navController = this.findNavController(R.id.myNavHostFragment)
   return NavigationUI.navigateUp(navController, drawerLayout)
}

Documentação para desenvolvimento em Android:

Documentação do material design:

Esta seção lista as possíveis tarefas de casa para os alunos que estão trabalhando neste tutorial como parte de um curso ministrado por um instrutor.

Construa e execute um aplicativo

Adicione um botão Rules e um botão About ao layout do TitleFragment conforme mostrado abaixo. Quando o usuário toca no botão Rules ou About, o aplicativo navega para o RulesFragment ou AboutFragment, conforme apropriado.

Para crédito extra:

Em cada um dos layouts do RulesFragment e do AboutFragment, adicione um botão Play que navega para o GameFragment como mostrado aqui:



Dica: Você precisa atualizar os layouts para esses dois fragmentos para ativar a vinculação de dados.

Altere a pilha de retorno para permitir o seguinte fluxo de usuário:

  1. O usuário toca no botão Play para ir da tela RulesFragment ou AboutFragment para o GameFragment.
  2. Em seguida, o usuário toca no botão Voltar na parte inferior da tela.
  3. O aplicativo navega de volta para o TitleFragment, não para o RulesFragment ou AboutFragment.

Em outras palavras, quando o usuário toca no botão Play enquanto visualiza as regras ou as informações sobre o jogo, então toca no botão Voltar, no RulesFragment ou no AboutFragment é removido da pilha de retorno.

Responda estas perguntas

Pergunta 1

Como você permite que seu projeto use componentes de navegação?

Pergunta 2

Onde estão definidas as rotas possíveis através do seu aplicativo?

Pergunta 3

Quais das seguintes afirmações sobre o NavHostFragment são verdadeiras? Selecione tudo que se aplica.

Pergunta 4

Quais das seguintes afirmações sobre o grafo de navegação são verdadeiras? Selecione tudo que se aplica.

Pergunta 5

Onde você define o ID de um fragmento para ser usado na navegação?

Pergunta 6

O aplicativo Notícias tem um NewsFragment que exibe um botão Show headlines. O objetivo é que, quando o usuário clicar neste botão, o aplicativo navegue para o HeadlinesFragment.

Suponha que você adicionou uma conexão do NewsFragment ao HeadlinesFragment no grafo de navegação, conforme mostrado aqui:

O que mais você precisa fazer para que, quando o usuário tocar no botão Show headlines, o aplicativo navegue para o HeadlinesFragment?

Pergunta 7

Quando os usuários navegam por um aplicativo, às vezes eles querem refazer seus passos de volta pelas telas que já visitaram.

Suponha o seguinte:

Quais das afirmações a seguir são verdadeiras em relação à navegação para frente e para trás no aplicativo? (Escolha todas as opções aplicáveis).

Pergunta 8

Quando os usuários navegam por um aplicativo, às vezes eles querem refazer seus passos de volta pelas telas que já visitaram. No entanto, você pode usar os atributos popUpTo e popUpToInclusive de uma ação para modificar o caminho de volta através do aplicativo.

Suponha o seguinte:

O usuário navega de fragmentA para fragmentB para fragmentC e, a seguir, toca no botão Voltar do sistema. Nessa situação, digamos que você deseja que o aplicativo navegue de volta para fragmentA (em vez de fragmentB). Qual é a maneira correta de definir os atributos popUpTo e popUpToInclusive?

Pergunta 9

Suponha que a ação action_headlinesFragment_to_newsArticle no grafo de destino tenha um valor popUpTo de newsFragment:

Suponha que o usuário abra o aplicativo e navegue pelas telas na seguinte sequência (sem usar o botão Voltar):

Abra o aplicativo na página inicial de Notícias> Manchetes> Detalhes de notícias

Quando o usuário está visualizando a tela News detail, o que acontece se ele tocar no botão Voltar do sistema na parte inferior da tela?

Selecione todas as opções aplicáveis ​​(lembrando que popUpTo é newsFragment).

Pergunta 10

Onde você define os itens de um menu?

Pergunta 11

Para habilitar o menu de opções em seu aplicativo, você precisa definir os itens de menu. Então o que você precisa fazer na Activity ou Fragment onde o menu de opções deve aparecer?

Selecione tudo que se aplica:

Pergunta 12

O que você precisa fazer para habilitar uma gaveta de navegação em seu aplicativo? Você pode assumir que seu projeto está usando o grafo de navegação e que você já definiu os itens de menu.

Selecione tudo que se aplica:


Pergunta 13

Continuando com a pergunta anterior, você precisa escrever algum código para permitir que a gaveta de navegação seja exibida quando o usuário deslizar do lado esquerdo da tela?

Em onCreate() dentro da Activity que cria o controlador de navegação, qual é o código correto a ser adicionado?

NavigationUI.setupWithNavController(
    navigationLayoutID, navigationMenuID)
NavigationUI.setupWithNavController(
    navigationView, navigationController)
NavigationDrawer.setupWithNavInterface(
    navigationView, navigationController)
NavigationDrawer.setupWithNavController(
    navigationView, navigationMenuID)

Pergunta 14

Como você adiciona suporte para o botão Acima na parte superior da tela para permitir que os usuários voltem à tela inicial do aplicativo de qualquer lugar no aplicativo? O que você precisa fazer na Activity relevante?

Selecione tudo que se aplica:

Envie seu aplicativo para avaliação

Orientação para avaliadores

Verifique se o aplicativo possui os seguintes recursos:

Para crédito extra:

As telas RulesFragment e AboutFragment possuem um botão Play que navega para o GameFragment conforme mostrado aqui:



Verifique se os layouts para esses dois fragmentos possuem vinculação de dados ativada.

Verifique o seguinte fluxo de usuário:

  1. Toque no botão Play para ir da tela do fragmento de regras ou da tela do fragmento de cerca para o fragmento do jogo.
  2. Pressione o botão Voltar do sistema na parte inferior da tela.

O aplicativo deve navegar de volta para o fragmento do título, não para o fragmento de regras ou sobre o fragmento.

Comece a próxima lição: 03.3. Iniciando uma atividade externa

Para obter enlaces para outros tutoriais neste curso, consulte a página de destino dos tutoriais Fundamentos de Android em Kotlin.