No tutorial anterior, você modificou o aplicativo AndroidTrivia para adicionar um fragmento a uma atividade existente. Neste tutorial, você adiciona navegação ao aplicativo.
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 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:
Para usar a biblioteca de navegação, você precisa adicionar as dependências de navegação aos seus arquivos Gradle.
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'
...
}
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"
...
}
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
.
activity_main.xml
, altere o nome do fragmento principal existente para
androidx.navigation.fragment.NavHostFragment
.myNavHostFragment
.app:navGraph
e defina-o para o recurso de grafo de navegação, que é
@navigation/navigation
.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.
TitleFragment
é onde os usuários do aplicativo começam quando abrem o aplicativo pela
primeira vez.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" />
action_titleFragment_to_gameFragment
.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.
TitleFragment.kt
. Dentro do método
onCreateView()
, adicione o seguinte código antes da instrução return
:binding.playButton.setOnClickListener{}
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)
}
TitleFragment.kt
:import androidx.navigation.findNavController
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:
GameWonFragment
leva o usuário a uma tela que mostra a mensagem "Congratulations!" mensagem.
GameOverFragment
leva o usuário a uma tela que mostra a mensagem "Try Again".navigation.xml
, que está na pasta navigation
.gameOverFragment
.gameWonFragment
.O editor de layout agora se parece com a seguinte captura de tela:
Nesta etapa, você conecta o fragmento de jogo ao fragmento de jogo vencido e ao fragmento de jogo terminado.
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.
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 {
}
}
}
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)
else
para perder o jogo, adicione o seguinte código, que navega para o
gameOverFragment
:view.findNavController().
navigate(R.id.action_gameFragment_to_gameOverFragment)
GameWonFragment
. 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
.
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:
popUpTo
de uma ação "desempilha" a pilha de retorno para um determinado destino
antes de navegar. (Os destinos são removidos da pilha de retorno).popUpToInclusive
for false
ou não estiver definido,
popUpTo
remove os destinos até o destino especificado, mas deixa o destino especificado na pilha
de retorno.
popUpToInclusive
for definido como true
, o atributo popUpTo
remove
todos os destinos até e incluindo o destino fornecido da pilha de retorno. popUpToInclusive
for true
e popUpTo
for definido como o local
inicial do aplicativo, a ação removerá todos os destinos do aplicativo da pilha de retorno. O botão
Voltar leva o usuário para fora do aplicativo.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.
navigation.xml
na pasta res > navigation. Se o grafo de navegação não
aparecer no editor de layout, clique na guia Design.gameFragment
para gameOverFragment
. (Na área de
pré-visualização, a ação é representada por uma linha azul que conecta os dois fragmentos).gameFragment
.
Selecione a caixa de seleção Inclusive.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).gameFragment
para o gameWonFragment
. Novamente,
defina Pop To para gameFragment
no painel Attributes e
selecione a caixa de seleção Inclusive.TitleFragment
.Atualmente, seu aplicativo tem o seguinte fluxo de usuário:
GameWon
ou
GameOver
.TitleFragment
. (Você implementou esse comportamento na Etapa 1 desta tarefa, acima).Nesta etapa, você implementa mais duas etapas do fluxo do usuário:
GameFragment
.TitleFragment
(em vez de voltar para a tela GameWon
ou GameOver
). Para criar este fluxo de usuário, use o atributo PopUpTo
para gerenciar a pilha de retorno:
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
.titleFragment
. 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.navigation.xml
, adicione uma ação de navegação conectando
gameWonFragment
a gameFragment
.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.
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)}
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)}
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")
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.
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:
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)
onCreate()
, adicione o código para vincular o controlador de navegação
à barra do aplicativo:
NavigationUI.setupActionBarWithNavController(this,navController)
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()
}
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.
navigation.xml
e clique na guia Design para ver o
grafo de navegação.ID
do fragmento seja
aboutFragment
.options_menu.xml
da pasta res > menu e clique na guia
Design para ver o editor de layout.Nesta etapa, você adiciona código para implementar o comportamento quando o usuário toca no item de menu About.
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
}
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)
}
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)
}
import android.view.*
para resolver várias
referências (e substituir importações mais específicas, como import android.view.ViewGroup
).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".
dependencies {
...
implementation "com.google.android.material:material:$supportlibVersion"
...
}
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:
fragment_rules.xml
para ver como ele se parece. Clique na guia
Design para ver a prévia no editor de design.navigation.xml
no Navigation Editor. Clique no botão New
Destination e adicione o fragmento de regras. Defina seu ID para
rulesFragment.
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.
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>
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" />
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.
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)
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.
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.
Mainactivity.kt
Kotlin, adicione a variável de membro lateinit
drawerLayout
para representar o layout da gaveta: private lateinit var drawerLayout: DrawerLayout
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
drawerLayout
como o terceiro parâmetro para o método
setupActionBarWithNavController()
:NavigationUI.setupActionBarWithNavController(this, navController, drawerLayout)
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)
}
import androidx.drawerlayout.widget.DrawerLayout
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
Para usar a biblioteca de navegação do Android, você precisa fazer algumas configurações:
navigation-fragment-ktx
e navigation-ui-ktx
no arquivo
build.gradle
de nível de módulo.ext
para a navigationVersion
no arquivo
build.gradle
de nível de projeto.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.
res/navigation
e é normalmente chamado de navigation.xml
.navigation.xml
e clique na
guia Design.navigation.xml
, cada uma dessas conexões é representada como uma
action
que possui um ID
. Um fragmento do host de navegação, geralmente denominado NavHostFragment
, atua como um
host para os fragmentos no grafo de navegação:
NavHostFragment
troca os fragmentos dentro e fora e gerencia a pilha de retorno do fragmento.activity_main.xml
, o NavHostFragment
é representado por um
elemento fragment
com o nome
android:name="androidx.navigation.fragment.NavHostFragment"
.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:
onClick
, chame findNavController().navigate()
na vista.ID
da action
que leva ao destino.Navegação condicional navega para uma tela em um caso e para uma tela diferente em outro caso. Para criar navegação condicional:
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 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:
popUpTo
no arquivo
navigation.xml
.popUpToInclusive
como true
. Todos os destinos até e incluindo este destino são removidos da pilha de
retorno.popUpTo
de uma ação for definido como o destino inicial do aplicativo e
popUpToInclusive
for definido como true
, o botão Voltar leva o usuário até o fim
fora do aplicativo.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:
onCreate()
, chame setupActionBarWithNavController()
na classe
NavigationUI
, passando no controlador de navegação:val navController = this.findNavController(R.id.myNavHostFragment)
NavigationUI.setupActionBarWithNavController(this,navController)
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 é 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:
options_menu.xml
. O arquivo é armazenado na pasta Res > Menu.options_menu.xml
no editor de design e arraste um widget Menu
Item do painel Palette para o menu.onClick
para o item de menu.3. Codifique o tratador onClick
para o item de menu:
onCreateView()
,
chamesetHasOptionsMenu(true)
para habilitar o menu de opções.onCreateOptionsMenu()
para inflar o menu de opções:override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater?) {
super.onCreateOptionsMenu(menu, inflater)
inflater?.inflate(R.menu.options_menu, menu)
}
onOptionsItemSelected()
para executar a ação apropriada quando o item de
menu for clicado. O código a seguir exibe o fragmento que possui o mesmo ID do item de menu. (Este código
somente funciona se o item de menu e o fragmento tiverem valores de ID idênticos).override fun onOptionsItemSelected(item: MenuItem?): Boolean {
return NavigationUI.onNavDestinationSelected(item!!,
view!!.findNavController())
|| super.onOptionsItemSelected(item)
}
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:
build.gradle (app)
.Essas etapas são explicadas com mais detalhes a seguir.
1. Adicione dependências a build.gradle
:
build.gradle (app)
:dependencies {
...
implementation "com.google.android.material:material:$supportlibVersion"
...
}
2. Provenha a cada fragmento de destino uma ID:
3. Crie o menu para a gaveta:
navdrawer_menu
) para um menu de gaveta de navegação. Isso cria um novo arquivo
navdrawer_menu.xml
na pasta Res> Menu
.4. Adicione a gaveta ao layout do fragmento:
<androidx.drawerlayout.widget.DrawerLayout>
como a vista raiz.<com.google.android.material.navigation.NavigationView>
ao layout.
5. Conecte a gaveta ao controlador de navegação:
onCreate()
, use NavigationUI.setupWithNavController()
para conectar a
gaveta de navegação 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:
onCreate()
na atividade que cria o controlador de navegação (que normalmente é a atividade
principal), passe o layout da gaveta como o terceiro parâmetro para
NavigationUI.setupActionBarWithNavController
: val binding = DataBindingUtil.setContentView<ActivityMainBinding>(
this, R.layout.activity_main)
NavigationUI.setupActionBarWithNavController(
this, navController, binding.drawerLayout)
onSupportNavigateUp()
para
retornar NavigationUI.navigateUp()
. Passe o controlador de navegação e o layout da gaveta para
navigateUp()
.override fun onSupportNavigateUp(): Boolean {
val navController = this.findNavController(R.id.myNavHostFragment)
return NavigationUI.navigateUp(navController, drawerLayout)
}
Documentação para desenvolvimento em Android:
NavigationUI
NavHostFragment
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.
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.
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:
RulesFragment
ou
AboutFragment
para o GameFragment
.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.
Como você permite que seu projeto use componentes de navegação?
Activity
estende a classe NavigationActivity
.
NavigationController
como a atividade de inicialização.<uses-navigation>
ao arquivo de manifesto do Android.navigation-fragment-ktx
e navigation-ui-ktx
no arquivo
build.gradle (module)
.Onde estão definidas as rotas possíveis através do seu aplicativo?
navigation.xml)
na pasta res > layout.
navigation.xml)
na pasta app >
navigation.
navigation.xml)
na pasta res >
navigation.
android-manifest.xml
no elemento <navigation>
.Quais das seguintes afirmações sobre o NavHostFragment
são verdadeiras? Selecione tudo que se
aplica.
NavHostFragment
troca os fragmentos dentro e fora conforme necessário.NavHostFragment
na vista do Projeto para abrir o grafo de navegação.NavHostFragment
ao layout principal adicionando um
<fragment>
cujo nome é androidx.navigation.fragment.NavHostFragment
. NavHostFragment
e implementar o método
onNavigate()
para tratar com diferentes tipos de navegação (como cliques em botões).Quais das seguintes afirmações sobre o grafo de navegação são verdadeiras? Selecione tudo que se aplica.
type
de uma conexão entre fragmentos é Action
.type="navigation"
a cada <fragment>
que está
incluído no grafo de navegação.navigation.xml
) no
painel Projeto do Android Studio e clique na guia Design.Onde você define o ID de um fragmento para ser usado na navegação?
ID
no editor de design ou no
arquivo XML de layout na pasta res > layout.ID
no grafo de navegação ou no
arquivo XML de navegação na pasta res > navigation.ID
na classe Fragment
relevante.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
?
onclickListener
para o botão Show headlines, chame navigate()
no controlador de navegação, passando o nome da classe do fragmento de destino (neste case
HeadlinesFragment
).onclickListener
do botão Show headlines, chame navigate()
no
controlador de navegação, passando a ação que conecta o NewsFragment
ao
HeadlinesFragment
.onclickListener
para o botão Show headlines, chame
navigateTo()
no fragmento do contêiner, passando o nome da classe do fragmento de destino (neste
case HeadlinesFragment
).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:
fragmentA
está conectado a fragmentB
por
action_FragmentA_to_FragmentB
.
fragmentB
está conectado a fragmentC
por
action_FragmentB_to_FragmentC
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).
action_FragmentA_to_FragmentB
especifica que quando o usuário está em
FragmentA
, o próximo destino no aplicativo é FragmentB
.action_FragmentA_to_FragmentB
define o próximo destino para o qual o usuário
vai, quer o usuário toque em um botão no aplicativo ou no botão Voltar na parte inferior da tela.
popUpTo
da ação pode modificar para onde o aplicativo navega se o usuário tocar no
botão Voltar do sistema.popUpTo
da ação pode modificar para onde o usuário vai em seguida enquanto navega
para frente pelo aplicativo.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:
fragmentA
está conectado a fragmentB
por
action_FragmentA_to_FragmentB
.
fragmentB
está conectado a fragmentC
por
action_FragmentB_to_FragmentC
.
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
fragment
A
(em vez de fragmentB
). Qual é a maneira
correta de definir os atributos popUpTo
e popUpToInclusive
?
action_FragmentA_to_FragmentB
, defina popUpTo
como fragmentB
e
popUpToInclusive
como nenhum valor.action_FragmentB_to_FragmentC
, defina
popUpTo
como fragmentA
e popUpToInclusive
como true
.action_FragmentA_to_FragmentB
, defina popUpTo
como fragmentA
e
popUpToInclusive
como true
.action_FragmentB_to_FragmentC
,
defina popUpTo
como fragmentA
e popUpToInclusive
como
true
.action_FragmentA_to_FragmentB
, defina popUpTo
como nenhum e
popUpToInclusive
como nenhum valor. (Você pode omitir os dois atributos).action_FragmentB_to_FragmentC
, defina popUpTo
como fragmentA
e
popUpToInclusive
como true
.action_FragmentA_to_FragmentB
, defina popUpTo
como nenhum e
popUpToInclusive
como nenhum valor. (Você pode omitir os dois atributos).action_FragmentB_to_FragmentC
, defina popUpTo
como fragmentA
e
popUpToInclusive
como false
. 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
).
popUpToInclusive
for true
:popUpToInclusive
for false
:popUpToInclusive
for true
:popUpToInclusive
for false
:Onde você define os itens de um menu?
<item>
para cada item de menu no arquivo menu
.xml
na
pasta res > drawer. Para o menu de opções, adicione uma etiqueta <item>
para cada item de menu no arquivo menu
.xml
em pasta res >
options.<menu>
que contém as etiquetas <item>
para cada item.menu_name
.xml
na pasta res > menu,
adicione um <item>
etiqueta para cada item de menu. Crie arquivos XML separados para cada
menu separado.android_manifest.xml
, adicione uma etiqueta <menus>
que contém
uma etiqueta <menu>
para cada menu. Para cada etiqueta <menu>
, adicione
uma etiqueta <item>
para cada item de menu.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:
setHasOptionsMenu(true)
em onCreate()
para uma atividade, ou em
onCreateView()
para um fragmento. onCreateOptionsMenu()
na atividade ou fragmento para criar o menu.onClick
no arquivo XML do menu para onShowOptionsMenu
, a menos
que esteja implementando um ouvinte onClick
personalizado para o menu de opções, nesse caso,
especifique o nome do ouvinte onClick
personalizado.onOptionsItemSelected()
na atividade ou fragmento para determinar o que acontece
quando um usuário seleciona um item de menu no menu de opções.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:
<DrawerLayout>
como a vista raiz no arquivo de layout relevante e adicione uma
etiqueta <NavigationView>
a esse layout. <Navigation>
como a vista raiz no arquivo de layout relevante e adicione uma etiqueta
<NavigationView>
a esse layout. <NavigationView>
no layout, defina o atributo android:menu
para o menu da
gaveta de navegação.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)
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:
res> menu
, crie o arquivo up_menu.xml
.NavigationUI.setupActionBarWithNavController(context,navigationController)
onSupportNavigateUp()
para chamar navigateUp()
no controlador
de navegação.ID
de
HomeFragment
.Verifique se o aplicativo possui os seguintes recursos:
TitleFragment
tem um botão Rules e About conforme
mostrado abaixo.RulesFragment
ou AboutFragment
, conforme apropriado. 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:
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:
Para obter enlaces para outros tutoriais neste curso, consulte a página de destino dos tutoriais Fundamentos de Android em Kotlin.