O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Atualizar componentes da IU com NavigationUI

O componente de arquitetura de navegação inclui uma classe NavigationUI. Essa classe contém métodos estáticos que gerenciam a navegação com a barra superior do app, a gaveta de navegação e a navegação inferior.

Detectar eventos de navegação

Interagir com o NavController é o principal método de navegação entre destinos. O NavController é responsável por substituir o conteúdo do NavHost pelo novo destino. Em muitos casos, os elementos da IU, como uma barra superior de apps ou outros controles de navegação persistentes, como um BottomNavigationBar, vivem fora do NavHost e precisam ser atualizados à medida que você navega entre os destinos.

NavController oferece uma interface OnDestinationChangedListener que é chamada quando o destino atual de ou dos argumentos dele mudam. Um novo listener pode ser registrado pelo método addOnDestinationChangedListener(). Observe que, ao chamar addOnDestinationChangedListener(), se o destino atual existir, ele será imediatamente enviado para o listener.

NavigationUI usa OnDestinationChangedListener para tornar esses componentes de IU comuns compatíveis com a navegação. No entanto, você também pode usar OnDestinationChangedListener sozinho para fazer com que qualquer IU personalizada ou lógica de negócios reconheça eventos de navegação.

Por exemplo, você pode ter elementos de IU comuns que pretende mostrar em algumas áreas do app e ocultar em outras. Usando seu próprio OnDestinationChangedListener, você pode exibir ou ocultar esses elementos da IU com base no destino, como mostrado no exemplo a seguir:

Kotlin

    navController.addOnDestinationChangedListener { _, destination, _ ->
       if(destination.id == R.id.full_screen_destination) {
           toolbar.visibility = View.GONE
           bottomNavigationView.visibility = View.GONE
       } else {
           toolbar.visibility = View.VISIBLE
           bottomNavigationView.visibility = View.VISIBLE
       }
    }
    

Java

    navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
       @Override
       public void onDestinationChanged(@NonNull NavController controller,
               @NonNull NavDestination destination, @Nullable Bundle arguments) {
           if(destination.getId() == R.id.full_screen_destination) {
               toolbar.setVisibility(View.GONE);
               bottomNavigationView.setVisibility(View.GONE);
           } else {
               toolbar.setVisibility(View.VISIBLE);
               bottomNavigationView.setVisibility(View.VISIBLE);
           }
       }
    });
    

Barra superior do app

A barra superior do app oferece um lugar consistente ao longo da parte superior do app para exibir informações e ações da tela atual.

NavigationUI contém métodos que atualizam automaticamente o conteúdo na barra superior à medida que os usuários navegam pelo app. Por exemplo, usa os rótulos de destino do gráfico de navegação para manter o título da barra superior do app atualizado.

Ao usar NavigationUI com os principais métodos da barra de apps discutidos abaixo, o rótulo anexado aos destinos pode ser preenchido automaticamente a partir dos argumentos fornecidos para o destino usando o formato {argName} no rótulo.

NavigationUI é compatível com os seguintes tipos de barra de apps:

AppBarConfiguration

NavigationUI usa um AppBarConfiguration para gerenciar o comportamento do botão "Navegação" no canto superior esquerdo da área de exibição do seu app. Por padrão, o botão "Navegação" fica oculto quando um usuário está em um destino de nível superior de um gráfico de navegação e aparece como um botão "Para cima" em qualquer outro destino.

Para usar o destino inicial do gráfico de navegação como o único destino de nível superior, você pode criar um AppBarConfiguration e passar o gráfico de navegação correspondente, conforme mostrado abaixo:

Kotlin

    val appBarConfiguration = AppBarConfiguration(navController.graph)
    

Java

    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    

Se quiser personalizar quais destinos são considerados de nível superior, você pode passar um conjunto de códigos de destino para o construtor, conforme mostrado abaixo:

Kotlin

    val appBarConfiguration = AppBarConfiguration(setOf(R.id.main, R.id.android))
    

Java

    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(R.id.main, R.id.android).build();
    

Criar uma barra de ferramentas

Para criar uma barra de ferramentas com NavigationUI, primeiro defina a barra na atividade principal, conforme mostrado abaixo:

    <LinearLayout>
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar" />
        <fragment
            android:id="@+id/nav_host_fragment"
            ... />
        ...
    </LinearLayout>
    

Em seguida, chame setupWithNavController() no método onCreate() da atividade principal, conforme mostrado abaixo:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        setContentView(R.layout.activity_main)

        ...

        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(navController.graph)
        findViewById<Toolbar>(R.id.toolbar)
            .setupWithNavController(navController, appBarConfiguration)
    }
    

Java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);

        ...

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        AppBarConfiguration appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph()).build();
        Toolbar toolbar = findViewById(R.id.toolbar);
        NavigationUI.setupWithNavController(toolbar, navController);
    }
    

Incluir CollapsingToolbarLayout

Para incluir um CollapsingToolbarLayout com a barra de ferramentas, primeiro defina a barra e o layout que a envolve na atividade principal, conforme mostrado abaixo:

    <LinearLayout>
        <android.support.design.widget.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="@dimen/tall_toolbar_height">

            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:contentScrim="?attr/colorPrimary"
                app:expandedTitleGravity="top"
                app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

                <android.support.v7.widget.Toolbar
                    android:id="@+id/toolbar"
                    android:layout_width="match_parent"
                    android:layout_height="?attr/actionBarSize"
                    app:layout_collapseMode="pin"/>
            </android.support.design.widget.CollapsingToolbarLayout>
        </android.support.design.widget.AppBarLayout>

        <fragment
            android:id="@+id/nav_host_fragment"
            ... />
        ...
    </LinearLayout>
    

Em seguida, chame setupWithNavController() no método onCreate da atividade principal, conforme mostrado abaixo:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        setContentView(R.layout.activity_main)

        ...

        val layout = findViewById<CollapsingToolbarLayout>(R.id.collapsing_toolbar_layout)
        val toolbar = findViewById<Toolbar>(R.id.toolbar)
        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(navController.graph)
        layout.setupWithNavController(toolbar, navController, appBarConfiguration)
    }
    

Java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);

        ...

        CollapsingToolbarLayout layout = findViewById(R.id.collapsing_toolbar_layout);
        Toolbar toolbar = findViewById(R.id.toolbar);
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        AppBarConfiguration appBarConfiguration =
                new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupWithNavController(layout, toolbar, navController, appBarConfiguration);
    }
    

Barra de ações

Para compatibilizar a navegação com a barra de ações padrão, chame o método setupActionBarWithNavController() da atividade principal onCreate(), como mostrado abaixo. É necessário declarar o AppBarConfiguration fora de onCreate(), já que você também o usa ao substituir onSupportNavigateUp():

Kotlin

    private lateinit var appBarConfiguration: AppBarConfiguration

    ...

    override fun onCreate(savedInstanceState: Bundle?) {
        ...

        val navController = findNavController(R.id.nav_host_fragment)
        appBarConfiguration = AppBarConfiguration(navController.graph)
        setupActionBarWithNavController(navController, appBarConfiguration)
    }
    

Java

    AppBarConfiguration appBarConfiguration;

    ...

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
    }
    

Em seguida, substitua onSupportNavigateUp() para gerenciar a navegação para cima:

Kotlin

    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment)
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }
    

Java

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, appBarConfiguration)
                || super.onSupportNavigateUp();
    }
    

Vincular destinos a itens de menu

NavigationUI também fornece assistentes para vincular destinos a componentes de IU orientados por menu. NavigationUI contém um assistente, onNavDestinationSelected(), que leva um MenuItem com o NavController que hospeda o destino associado. Se o id do MenuItem corresponder ao id do destino, NavController poderá navegar para esse destino.

Por exemplo, os snippets de XML abaixo definem um item de menu e um destino com um id comum, details_page_fragment:

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:android="http://schemas.android.com/apk/res/android"
        ... >

        ...

        <fragment android:id="@+id/details_page_fragment"
             android:label="@string/details"
             android:name="com.example.android.myapp.DetailsFragment" />
    </navigation>
    
    <menu xmlns:android="http://schemas.android.com/apk/res/android">

        ...

        <item
            android:id="@id/details_page_fragment"
            android:icon="@drawable/ic_details"
            android:title="@string/details" />
    </menu>
    

Se o menu foi adicionado por onCreateOptionsMenu() da atividade, por exemplo, você poderá associar os itens de menu aos destinos modificando onOptionsItemSelected() da atividade para chamar onNavDestinationSelected(), conforme mostrado abaixo:

Kotlin

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        val navController = findNavController(R.id.nav_host_fragment)
        return item.onNavDestinationSelected(navController) || super.onOptionsItemSelected(item)
    }
    

Java

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.onNavDestinationSelected(item, navController)
                || super.onOptionsItemSelected(item);
    }
    

Agora, quando um usuário clica no item de menu details_page_fragment, o app navega automaticamente para o destino correspondente com o mesmo id.

Adicionar uma gaveta de navegação

A gaveta de navegação é um painel da IU que mostra o menu de navegação principal do app. A gaveta aparece quando o usuário toca no ícone da gaveta na barra do app ou quando o usuário desliza um dedo a partir da borda esquerda da tela.

O ícone da gaveta é exibido em todos os destinos de nível superior que usam um DrawerLayout. Destinos de nível superior são os destinos de nível raiz do app. Eles não exibem um botão "Para cima" na barra de apps.

Para adicionar uma gaveta de navegação, primeiro declare DrawerLayout como a visualização raiz. Dentro de DrawerLayout, adicione um layout para o conteúdo principal da IU e outra visualização com o conteúdo da gaveta de navegação.

Por exemplo, o layout a seguir usa um DrawerLayout com duas visualizações filhas: uma NavHostFragment para o conteúdo principal e uma NavigationView para o conteúdo da gaveta de navegação.

<?xml version="1.0" encoding="utf-8"?>
    <!-- Use DrawerLayout as root container for activity -->
    <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

        <!-- Layout to contain contents of main body of screen (drawer will slide over this) -->
        <fragment
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:id="@+id/nav_host_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:navGraph="@navigation/nav_graph" />

        <!-- Container for contents of drawer - use NavigationView to make configuration easier -->
        <android.support.design.widget.NavigationView
            android:id="@+id/nav_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            android:fitsSystemWindows="true" />

    </android.support.v4.widget.DrawerLayout>
    

Em seguida, conecte o DrawerLayout ao gráfico de navegação, passando-o para AppBarConfiguration, conforme mostrado abaixo:

Kotlin

    val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)
    

Java

    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph())
                .setDrawerLayout(drawerLayout)
                .build();
    

Em seguida, na classe de atividade principal, chame setupWithNavController() do método onCreate() das atividades principais, conforme mostrado abaixo:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        setContentView(R.layout.activity_main)

        ...

        val navController = findNavController(R.id.nav_host_fragment)
        findViewById<NavigationView>(R.id.nav_view)
            .setupWithNavController(navController)
    }
    

Java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);

        ...

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationView navView = findViewById(R.id.nav_view);
        NavigationUI.setupWithNavController(navView, navController);
    }
    

Navegação inferior

NavigationUI também pode gerenciar a navegação inferior. Quando um usuário seleciona um item de menu, o NavController chama onNavDestinationSelected() e atualiza automaticamente o item selecionado na barra de navegação inferior.

Para criar uma barra de navegação inferior no app, primeiro defina a barra na atividade principal, conforme mostrado abaixo:

    <LinearLayout>
        ...
        <fragment
            android:id="@+id/nav_host_fragment"
            ... />
        <android.support.design.widget.BottomNavigationView
            android:id="@+id/bottom_nav"
            app:menu="@menu/menu_bottom_nav" />
    </LinearLayout>
    

Em seguida, na classe de atividade principal, chame setupWithNavController() do método onCreate() das atividades principais, conforme mostrado abaixo:

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        setContentView(R.layout.activity_main)

        ...

        val navController = findNavController(R.id.nav_host_fragment)
        findViewById<BottomNavigationView>(R.id.bottom_nav)
            .setupWithNavController(navController)
    }
    

Java

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);

        ...

        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
        NavigationUI.setupWithNavController(bottomNav, navController);
    }
    

Para ver um exemplo abrangente que inclua navegação na parte inferior, consulte Amostra de navegação avançada para componentes da arquitetura do Android no GitHub (link em inglês).

Outros recursos

Para saber mais sobre navegação, consulte os seguintes recursos.

Amostras

Codelabs

Postagens do blog

Vídeos