Google berkomitmen untuk mendorong terwujudnya keadilan ras bagi komunitas Kulit Hitam. Lihat caranya.

Mengupdate komponen UI dengan NavigationUI

Komponen Navigation menyertakan class NavigationUI. Class ini berisi metode statis yang mengelola navigasi dengan panel aplikasi atas, panel navigasi, dan navigasi bawah.

Panel aplikasi atas

Panel aplikasi atas menyediakan tempat yang konsisten di seluruh bagian atas aplikasi Anda untuk menampilkan informasi dan tindakan dari layar yang sedang dibuka.

layar menampilkan panel aplikasi atas
Gambar 1. Layar menampilkan panel aplikasi atas.

NavigationUI berisi metode yang mengupdate konten di panel aplikasi atas secara otomatis saat pengguna melakukan navigasi dalam aplikasi Anda. Misalnya, NavigationUI menggunakan label tujuan dari grafik navigasi untuk terus mengupdate judul panel aplikasi atas.

<navigation>
    <fragment ...
              android:label="Page title">
      ...
    </fragment>
</navigation>

Saat menggunakan NavigationUI dengan implementasi panel aplikasi atas yang dibahas di bawah, label yang dilampirkan ke tujuan dapat diisi secara otomatis dari argumen yang diberikan ke tujuan dengan menggunakan format {argName} di label Anda.

NavigationUI memberikan dukungan untuk jenis panel aplikasi atas berikut:

Untuk informasi selengkapnya tentang panel aplikasi, lihat Menyiapkan panel aplikasi.

AppBarConfiguration

NavigationUI menggunakan objek AppBarConfiguration untuk mengelola perilaku tombol Navigation di sudut kiri atas bagian tampilan aplikasi Anda. Perilaku tombol Navigation berubah-ubah, tergantung apakah pengguna berada di tujuan level atas.

Tujuan level atas adalah tujuan utama atau tujuan level teratas, dalam sekumpulan tujuan yang terkait secara hierarki. Tujuan level atas tidak menampilkan tombol Atas di panel aplikasi atas karena tidak ada tujuan level yang lebih tinggi. Secara default, tujuan awal aplikasi Anda adalah satu-satunya tujuan level atas.

Saat pengguna berada di tujuan level atas, tombol Navigation menjadi ikon panel samping jika tujuan menggunakan DrawerLayout. Jika tujuan tidak menggunakan DrawerLayout, tombol Navigation akan disembunyikan. Saat pengguna berada di tujuan lain, tombol Navigation muncul sebagai tombol Atas . Untuk mengonfigurasi tombol Navigation hanya menggunakan tujuan awal sebagai tujuan level atas, buat objek AppBarConfiguration, dan masukkan grafik navigasi yang sesuai, seperti yang ditunjukkan di bawah ini:

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph)

Java

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

Dalam beberapa kasus, Anda mungkin perlu menentukan beberapa tujuan level atas, bukan menggunakan tujuan awal default. Dalam hal ini, penggunaan BottomNavigationView adalah kasus penggunaan umum, yang membuat Anda mungkin memiliki layar setara yang satu sama lain tidak terkait dan dapat memiliki kumpulan tujuan terkait sendiri. Untuk kasus seperti ini, Anda dapat meneruskan serangkaian ID tujuan ke konstruktor, seperti yang ditunjukkan di bawah:

Kotlin

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

Java

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

Membuat Toolbar

Untuk membuat Toolbar dengan NavigationUI, pertama-tama tentukan panel dalam aktivitas utama Anda, seperti yang ditunjukkan di bawah:

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar" />
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    ...
</LinearLayout>

Selanjutnya, panggil setupWithNavController() dari metode onCreate() aktivitas utama Anda, seperti yang ditunjukkan dalam contoh berikut:

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, appBarConfiguration);
}

Menyertakan CollapsingToolbarLayout

Untuk menyertakan CollapsingToolbarLayout dengan Toolbar, terlebih dahulu tentukan Toolbar dan tata letak di sekitarnya, dalam aktivitas utama Anda, seperti yang ditunjukkan di bawah:

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/tall_toolbar_height">

        <com.google.android.material.appbar.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">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                app:layout_collapseMode="pin"/>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

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

Selanjutnya, panggil setupWithNavController() dari metode onCreate aktivitas utama Anda, seperti yang ditunjukkan di bawah:

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 navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    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);
    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupWithNavController(layout, toolbar, navController, appBarConfiguration);
}

Panel tindakan

Untuk menambahkan dukungan navigasi ke panel tindakan default, panggil setupActionBarWithNavController() dari metode onCreate() aktivitas utama Anda, seperti yang ditunjukkan di bawah. Perhatikan bahwa Anda perlu mendeklarasikan AppBarConfiguration di luar onCreate(), karena Anda juga perlu menggunakannya saat mengganti onSupportNavigateUp():

Kotlin

private lateinit var appBarConfiguration: AppBarConfiguration

...

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

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
}

Java

AppBarConfiguration appBarConfiguration;

...

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

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
    NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}

Setelah itu, ganti onSupportNavigateUp() untuk menangani navigasi Atas:

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();
}

Mendukung variasi panel aplikasi

Menambahkan panel aplikasi atas ke aktivitas akan berfungsi dengan baik jika tata letak panel aplikasi serupa untuk setiap tujuan di aplikasi Anda. Namun, jika panel aplikasi atas Anda berubah secara substansial di seluruh tujuan, pertimbangkan untuk menghapus panel aplikasi atas dari aktivitas Anda dan menentukannya di setiap fragmen tujuan.

Misalnya, salah satu tujuan Anda mungkin menggunakan Toolbar standar, sementara yang lain menggunakan AppBarLayout untuk membuat panel aplikasi yang lebih kompleks dengan tab, seperti yang ditunjukkan pada gambar 2.

dua variasi panel aplikasi atas; toolbar standar di sebelah kiri, dan appbarlayout dengan toolbar dan tab di sebelah kanan
Gambar 2. Dua variasi panel aplikasi. Di sebelah kiri, Toolbar standar. Di sebelah kanan, AppBarLayout dengan Toolbar dan tab.

Untuk menerapkan contoh ini dalam fragmen tujuan Anda menggunakan NavigationUI, terlebih dahulu tentukan panel aplikasi di setiap tata letak fragmen, dimulai dengan fragmen tujuan yang menggunakan toolbar standar:

<LinearLayout>
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        ... />
    ...
</LinearLayout>

Selanjutnya, tentukan fragmen tujuan yang menggunakan panel aplikasi dengan tab:

<LinearLayout>
    <com.google.android.material.appbar.AppBarLayout
        ... />

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            ... />

        <com.google.android.material.tabs.TabLayout
            ... />

    </com.google.android.material.appbar.AppBarLayout>
    ...
</LinearLayout>

Logika konfigurasi navigasi sama untuk kedua fragmen ini, kecuali Anda harus memanggil setupWithNavController() dari dalam setiap metode onViewCreated() fragmen, alih-alih melakukan inisialisasi dari aktivitas:

Kotlin

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    val navController = findNavController()
    val appBarConfiguration = AppBarConfiguration(navController.graph)

    view.findViewById<Toolbar>(R.id.toolbar)
            .setupWithNavController(navController, appBarConfiguration)
}

Java

@Override
public void onViewCreated(@NonNull View view,
                          @Nullable Bundle savedInstanceState) {
    NavController navController = Navigation.findNavController(view);
    AppBarConfiguration appBarConfiguration =
            new AppBarConfiguration.Builder(navController.getGraph()).build();
    Toolbar toolbar = view.findViewById(R.id.toolbar);

    NavigationUI.setupWithNavController(
            toolbar, navController, appBarConfiguration);
}

Menyatukan tujuan ke item menu

NavigationUI juga menyediakan helper untuk menyatukan tujuan ke komponen UI berdasarkan menu. NavigationUI berisi metode helper, onNavDestinationSelected(), yang mengambil MenuItem bersama dengan NavController yang menghosting tujuan terkait. Jika id dari MenuItem cocok dengan id tujuan, NavController kemudian dapat menavigasi ke tujuan tersebut.

Sebagai contoh, cuplikan XML di bawah ini menentukan item menu dan tujuan dengan id umum, yaitu 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>

Jika menu Anda ditambahkan melalui onCreateOptionsMenu() Aktivitas, misalnya, Anda dapat mengaitkan item menu dengan tujuan dengan mengganti onOptionsItemSelected() Aktivitas untuk memanggil onNavDestinationSelected(), seperti yang ditunjukkan dalam contoh berikut:

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);
}

Sekarang, saat pengguna mengeklik item menu details_page_fragment, aplikasi akan otomatis menavigasi ke tujuan yang sesuai dengan id yang sama.

Menambahkan panel navigasi

Panel navigasi adalah panel UI yang menampilkan menu navigasi utama aplikasi Anda. Panel samping ini akan muncul saat pengguna menyentuh ikon panel samping di panel aplikasi atau saat pengguna menggeser jari dari tepi kiri layar.

panel samping terbuka yang menampilkan menu navigasi
Gambar 3. Panel terbuka yang menampilkan menu navigasi.

Ikon panel samping ditampilkan di semua tujuan level atas yang menggunakan DrawerLayout.

Untuk menambahkan panel navigasi, terlebih dahulu deklarasikan DrawerLayout sebagai tampilan root. Di dalam DrawerLayout, tambahkan tata letak untuk konten UI utama dan tampilan lain yang berisi konten panel navigasi.

Misalnya, tata letak berikut menggunakan DrawerLayout dengan dua tampilan turunan: NavHostFragment untuk menyertakan konten utama dan NavigationView untuk konten panel navigasi.

<?xml version="1.0" encoding="utf-8"?>
<!-- Use DrawerLayout as root container for activity -->
<androidx.drawerlayout.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) -->
    <androidx.fragment.app.FragmentContainerView
        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 -->
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true" />

</androidx.drawerlayout.widget.DrawerLayout>

Selanjutnya, hubungkan DrawerLayout ke grafik navigasi dengan meneruskannya ke AppBarConfiguration, seperti yang ditunjukkan dalam contoh berikut:

Kotlin

val appBarConfiguration = AppBarConfiguration(navController.graph, drawerLayout)

Java

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

Selanjutnya, dalam class aktivitas utama Anda, panggil setupWithNavController() dari metode onCreate() aktivitas utama, seperti yang ditunjukkan di bawah:

Kotlin

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

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<NavigationView>(R.id.nav_view)
        .setupWithNavController(navController)
}

Java

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

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    NavigationView navView = findViewById(R.id.nav_view);
    NavigationUI.setupWithNavController(navView, navController);
}

Navigasi bawah

NavigationUI juga dapat menangani navigasi bawah. Saat pengguna memilih item menu, NavController akan memanggil onNavDestinationSelected() dan otomatis mengupdate item yang dipilih di menu navigasi bawah.

menu navigasi bawah
Gambar 4. Menu navigasi bawah.

Untuk membuat menu navigasi bawah di aplikasi, terlebih dahulu tentukan panel di aktivitas utama Anda, seperti yang ditunjukkan di bawah:

<LinearLayout>
    ...
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        ... />
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        app:menu="@menu/menu_bottom_nav" />
</LinearLayout>

Selanjutnya, dalam class aktivitas utama Anda, panggil setupWithNavController() dari metode onCreate() aktivitas utama, seperti yang ditunjukkan di bawah:

Kotlin

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

    ...

    val navHostFragment =
        supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
    val navController = navHostFragment.navController
    findViewById<BottomNavigationView>(R.id.bottom_nav)
        .setupWithNavController(navController)
}

Java

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

    ...

    NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment);
    NavController navController = navHostFragment.getNavController();
    BottomNavigationView bottomNav = findViewById(R.id.bottom_nav);
    NavigationUI.setupWithNavController(bottomNav, navController);
}

Untuk contoh komprehensif yang menyertakan navigasi bawah, lihat Contoh Navigasi Lanjutan Komponen Arsitektur Android di GitHub.

Memproses peristiwa navigasi

Berinteraksi dengan NavController adalah metode utama untuk melakukan navigasi antartujuan. NavController bertanggung jawab untuk mengganti konten NavHost dengan tujuan baru. Pada banyak kasus, elemen UI—seperti panel aplikasi atas atau kontrol navigasi tetap lainnya seperti BottomNavigationBar—berada di luar NavHost dan perlu diupdate saat Anda melakukan navigasi antartujuan.

NavController menyediakan antarmuka OnDestinationChangedListener yang dipanggil saat tujuan saat ini dari NavController atau argumennya berubah. Pemroses baru dapat didaftarkan melalui metode addOnDestinationChangedListener(). Perhatikan bahwa saat memanggil addOnDestinationChangedListener(), jika tujuan saat ini ada, tujuan akan segera dikirim ke pemroses Anda.

NavigationUI menggunakan OnDestinationChangedListener untuk membuat komponen UI umum ini mengenali navigasi. Namun, perhatikan bahwa Anda juga dapat hanya menggunakan OnDestinationChangedListener untuk membuat UI kustom atau logika bisnis apa saja mengenali peristiwa navigasi.

Misalnya, Anda mungkin memiliki elemen UI umum yang ingin ditampilkan di beberapa bagian aplikasi dan disembunyikan di bagian lain. Dengan menggunakan OnDestinationChangedListener sendiri, Anda dapat secara selektif menampilkan atau menyembunyikan elemen UI ini berdasarkan tujuan target, seperti dalam contoh berikut:

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);
       }
   }
});

Referensi lainnya

Untuk mempelajari navigasi lebih lanjut, lihat referensi tambahan berikut.

Contoh

Codelab

Postingan blog

Video