# Örnek-4: Navigation Komponenti ile ActionBar ve DrawerLayout Kullanımı

**Navigation** komponenti içerisinde [NavigationUI](https://developer.android.com/reference/androidx/navigation/ui/NavigationUI.html) sınıfını içerir. Bu sınıf, **app bar**, **navigation drawer** ve **bottom navigation** ile navigasyonu yönetmenizi sağlayan statik metotlar içerir. Bu sayede Navigation komponentinden önce yapmak zorunda kaldığımız pek çok şeyi yapmadan, bu bileşenlerin yönetimini navigation komponentine bırakır. Bu örneğimizinde bunu nasıl gerçekleştiğini incelemeye çalışacağız.

Artık dördüncü örneğimize ulaştığımız için örneğimiz de gittikçe büyümeye başladı. Bu yüzden kod üzerindeki değişiklikleri aşağıda belirttiğim Github adresi üzerinden takip edebilirsiniz.

{% embed url="<https://github.com/egemenmede/jpnavigation1>" %}

O halde başlayalım..

İlk olarak **activity\_main.xml** dosyamızı güncelleyerek başlıyoruz. **DrawerLayout** ve **AppBar** eklemelerimizi aşağıdaki gibi gerçekleştiriyoruz.

```markup
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity"
    tools:openDrawer="start">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:animateLayoutChanges="true"
            android:theme="@style/AppTheme.AppBarOverlay">
            <androidx.appcompat.widget.Toolbar
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                android:id="@+id/toolbar"/>
        </com.google.android.material.appbar.AppBarLayout>
        <fragment
            android:id="@+id/nav_host_fragment"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:defaultNavHost="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/appbar"
            app:navGraph="@navigation/nav_graph" />
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

    <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:background="@android:color/white"

        android:fitsSystemWindows="true"
        android:isScrollContainer="true"
        android:saveEnabled="true"
        android:scrollY="1dp"
        android:scrollbars="none"
        app:elevation="2dp"
        app:headerLayout="@layout/nav_header"
        app:insetForeground="@color/colorPrimaryDark"

        app:itemIconTint="@color/colorPrimaryDark"
        app:menu="@menu/navigation_menu" />

</androidx.drawerlayout.widget.DrawerLayout>
```

**XML** üzerinde yaptığımız değişiklikler aslında **nav\_host\_fragment**'i saymazsak bu güne kadar Android geliştirme sırasında yaptıklarımızdan farklı değil. Bu yüzden vakit kaybetmeden esas aksiyonu alacağımız **MainActivity.kt**'ye geçelim.

Biliyorsunuz örneğimiz single activity şekliden fragment'ler ile yönettiğimiz bir yapıda. Dolayısıyla normalde olsa fragmentleri yönetmek için bol bol **FragmentTransaction** ve **StartActivity**'ler kullanarak bunları yönetmemiz gerekiyor. Fakat bunları bizim adımıza Navigation komponent nasıl yapıyor dikkat etmeye çalışalım.

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    
    drawerLayout = findViewById(R.id.drawer_layout)
    navView = findViewById(R.id.nav_view)
    toolbar = findViewById(R.id.toolbar)
    
    navController = findNavController(R.id.nav_host_fragment)
    appBarConfig = AppBarConfiguration(navController.graph, drawerLayout)
    
    setupActionBar(navController, appBarConfig)
    setupNavigationController(navController)
}
```

**onCreate** metodu içerisinde gerekli olan bölümleri **findViewById** ile aldıktan sonra **appBarConfig** değişkeni ile tanımladığımız **AppBarConfiguration** oluşturuyoruz. **AppBarConfiguration**'u ilke parametresinde bizden **navController**'ımızın yönettiği **graph**'ı alıyor. Bu aslında bizim **nav\_graph.xml** olarak bildiğimiz Navigasyon komponentinin **Navigation Graph** özelliği. Yani şu anda hangi sayfa birbiri ile nasıl bağlı, aralarında hangi action'lar var bu action'lar hangi destination'ları gidiyor hepsini biliyor. İkinci parametre olarak da **DrawerLayout**'umuzu kendisine veriyoruz. Bunun bir yönüyle anlamı artık DrawerLayout'un yönetiminin konfigürasyonunu ona bırakıyoruz demek. Bu arada bu kullandığımız da dahil olmak üzere **AppBarConfiguration'**&#x131;n 3 farklı **constructor**'ı bulunuyor. Android Studio üzerinden diğerlerini de inceleyebilirsiniz.&#x20;

![DrawerLayout](/files/-M-n7-2zVsATFUi4K5Ne)

**setupActionBar** ve **setupNavigationController** isimli metotlar benim hazırladığım metotları oluşturuyor.

```kotlin
private fun setupNavigationController(navController: NavController) {
    navView.setupWithNavController(navController)
}
```

**setupNavigationController** metodunda dikkat ettiyseniz **navView** isimli bileşen ile bileşene ait **setupWithNavController** metoduna **navController**'ımızı atıyoruz. Bunun anlamı şudur; bu işlem **NavController** ile kullanmak için bir **NavigationView** ayarlar. Dolayısıyla **NavigationView** içerisindeki menülerden biri seçildiğinde menü item'ine ait **onNavDestinationSelected** metodu çağırılacak ve gitmesi gereken **destination**'a gidecektir. Bunun yönetimini de bizim adımıza Navigation komponent gerçekleştirecektir.

```kotlin
private fun setupActionBar(
        navController: NavController,
        appBarConfig: AppBarConfiguration
    ) {
    setSupportActionBar(toolbar)
    supportActionBar?.let {
        it.setDisplayHomeAsUpEnabled(true)
        it.setHomeAsUpIndicator(R.drawable.ic_menu_24px)
        it.setTitle(R.string.app_name)
    }

    setupActionBarWithNavController(navController, appBarConfig)
}
```

setActionBar metodunda ise hem bir ActionBar oluşturup çeşitli özelliklerini belirleyip, aynı zaman da **setupActionBarWithNavController** ile yönetimini yine Navigation komponente devrediyoruz. Örneğin; bu yöntemi çağırarak, **destination** değiştiğinde **ActionBar** üzerindeki başlık otomatik olarak güncellenir. Bunu **setupActionBarWithNavController** yönetir ve bu bilgi **NavDestination'**&#x61; ait **getLabel** metodundan sağlanır.

![Başlıklar label ismine göre otomatik olarak değişir](/files/-M-n77-3mhvYpr7alt0g)

Şimdi aşağıdaki gibi **nav\_graph.xml**'deki label'ların ne işe yaradığı şimdi daha net anlaşılıyor değil mi?

```kotlin
<fragment
    android:id="@+id/blankFragment"
    android:name="com.etiya.jpnavigation1.BlankFragment"
    android:label="fragment_blank"
    tools:layout="@layout/fragment_blank">
    <action
        android:id="@+id/action_blankFragment_to_blankFragment2"
        app:destination="@id/navigation" />
    <action
        android:id="@+id/action_blankFragment_to_blankFragment4"
        app:destination="@id/blankFragment4" />
    <action
        android:id="@+id/action_blankFragment_to_optionsMenuFragment"
        app:destination="@id/optionsMenuFragment" />
</fragment>
```

Bunun yanında **ActionBar**'daki **menü ikonu** (hamburger simgesi) ve geri düğmelerinin görüntülenmesini de yine **setupActionBarWithNavController** yönetir. Hangi durumda menü simgesi, hangi durumda geri butonunun çıkmasını **nav\_graph.xml** içerisindeki **action**'lara göre yönetilir.

Ancak navigasyon butonunu işlemek için **NavController**'a ait **navigateUp**'ı çağırmaktan siz sorumlusunuz. Bu yüzden aşağıdaki gibi **onSupportNavigateUp** metodunu **override** edip, yönetimini **navController**'a bırakmamız gerekiyor.

```kotlin
override fun onSupportNavigateUp(): Boolean {
    return navController.navigateUp(appBarConfig) || super.onSupportNavigateUp()
}
```

Bu işlemi gerçekleştirmezseniz cihazınızdaki donanımsal **geri** butonu ile sayfalarınızı yönetebilirsiniz, ancak **ActionBar** üzerinde bulunan **hamburger menü** ya da **geri** butonu tıklansa da herhangi bir işlem gerçekleştirmeyecektir.

Bunun sebebini biraz daha teknik bir şekilde açıklayalım. **onSupportNavigateUp**, **AppCompatActivity**'den gelir. **NavigationUI**'ın geri işlemi, hamburger menü gösterimi ve hatta drawer menüsünü doğru bir şekilde destekleyebilmesi için **override** edilerek geçersiz kılınması ve yönetiminin **NavigationUI**'a devredilmesi gerekir. Çünkü **AppCompatActivity** ve **NavigationUI** iki bağımsız komponenttir. Ancak **toolbar**'ınızı her şeyi ile kendiniz yönetmek istiyorsanız override etmeniz gerekmez.

Uygulamanın son halini yukarıdaki Github bağlantısından indirerek kendi denemelerinizi gerçekleştirebilirsiniz.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://egemen-mede.gitbook.io/jetpack-navigation/11.-talk-is-cheap-show-me-the-code/oernek-4-navigation-komponenti-ile-actionbar-ve-drawerlayout-kullanimi.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
