Örnek-3: Navigation Komponenti ile Options Menu Kullanımı

Android'te sık kullanılan menü çeşitlerinden olan Option Menu'ler ile Navigation komponentini nasıl kullanacağımıza göz atacağız.

İlk iş olarak Option Menu'nün XML dosyasını hazırlamaya başlayalım. Bunun için aşağıdaki ekran görüntüsünde olduğu gibi projemizin res klasörünün üzerine gidip sağ tıklayalım ve Android Resource File seçeneğini işaretleyelim.

Açılacak dialog penceresinde File name alanına menu yazıp, Resource Type bölümünden de Menu'yu seçelim ve OK butonuna basalım.

Daha sonra res klasörü altında oluşan menu > menu.xml dosyasının dizayn bölümünde aşağıdaki gibi açalım. Sol üst kısımdaki Palette bölümünden bir Menu Item'i menu altına sürükleyerek Options Menu Item ismini verelim.

Id değerini şimdilik boş bıraktım. Neden olduğunu birazdan açıklayacağım.

Oluşacak XML dosyamız aşağıdaki gibi olacaktır.

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

    <item
        android:id="@+id/myOptionMenu"
        android:title="Options Menu Item" />
</menu>

Şimdi önceki derslerimizde öğrendiğimiz gibi nav_graph.xml dosyamızı açarak OptionsMenuFragment isimli yeni bir fragment oluşturalım. Aşağıdaki gibi destination'lara ekleyelim ve BlankFragment destinasyonundan OptionsMenuFragment destinasyonuna giden yeni bir action oluşturalım.

XML kısmında ise kodum şu şekilde eklenmiş oldu.

<fragment
        android:id="@+id/optionsMenuFragment"
        android:name="com.etiya.jpnavigation1.OptionsMenuFragment"
        android:label="fragment_options_menu"
        tools:layout="@layout/fragment_options_menu" />

Menümüzü tüm sayfalardan kullanılabilmesi için MainActivity.kt dosyamızı açarak, aşağıdaki gibi düzenleyelim.

class MainActivity : AppCompatActivity() {

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

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        val inflater = menuInflater
        inflater.inflate(R.menu.menu, menu)
        return super.onCreateOptionsMenu(menu)
    }

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

Options Menu kullanımı için onCreateOptionMenu metodunu ve onOptionItemSelected metodlarını ekledik. Burada özellikle onOptionItemSelected'teki işlemlere değinmek istiyorum. Normalde biliyorsunuz Android geliştirme yaparken onOptionItemSelected içerisinde seçili olan item'lerin ID'leri kontrol edilir, hangi ID'ye sahip menü tıklanmışsa bir aksiyon alınırdı. Dikkat ettiyseniz artık bu ID karşılaştırmaları yok! Peki ilişkilendirme nasıl yapılacak? Bu örneğimizin en önemli ipucu bu aslında.

val navController = findNavController(R.id.nav_host_fragment)
item.onNavDestinationSelected(navController)

Yukarıdaki kod parçası ile navHost'unuza ait navController'ınızı onNavDestinationSelected metoduna verdiğinizde, gelen item sorunsuz bir şekilde istediğiniz destination'a gidebiliyorsa true değer döndürür ve navigasyonunuz gerçekleşir. Ancak bu ilişkilendirmeyi sağlamak için örneğimize göre gideceğiniz Fragment'in ID bilgisini, menu.xml'deki ilgili menüye ID olarak vermenizdir. Eğer farklı bir isim verirseniz kodunuz hata vermeyecek, ama yapması gereken navigasyonu yapmayacaktır. Bu yüzden yukarıda şimdilik bol bıraktığımız ID değerini değiştirmek için menu.xml dosyasını aşağıdaki gibi düzenleyelim.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/optionsMenuFragment"
        android:title="Options Menu Item" />
</menu>

Bu düzenlemeden sonra artık Options Menu üzerindeki "Options Menu Item" seçeneğine tıkladığımızda OptionsMenuFragment'in içeriğini görüntüleyebiliriz. OptionsMenuFragment'in layout içeriğini de aşağıdaki düzenlemeyi unutmayın.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".OptionsMenuFragment">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/tvMessage"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/options_menu_fragment" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</FrameLayout>

Son ekranlarımız da şu şekilde oluştu.

Options Menu Item seçeneğini işaretlediğimizde artık, ilgili Fragment'in içerisindeyiz.

Şimdi gelelim bu örneğimizde öğrenmemiz gereken ikini ipucuna..

Örneğimiz üzerinden şöyle bir senaryomuz olsun.

  1. Uygulama açılır. (BlankFragment)

  2. Adınızı Giriniz bölümü doldurulur ve Fragment4'e gidilir. (BlankFragment4)

  3. BlankFragment4 içerisinde options menüye tıklanır. (OptionsMenuFragment)

Bu senaryoya göre artık mobil cihazım üzerinde back/geri tuşuna bastığımda varsayılan olarak startDestination neresi ise uygulama oraya geri döner. Yani senaryomuza göre OptionsMenuFragment sayfasındayken geri butonuna bastığımızda uygulama startDestination'ımız BlankFragment olduğu için o sayfaya geri dönecektir.

Eğer uygulamanızın bu şekilde çalışmasını istemiyor ve geldiği gibi geri gitmesini istiyorsanız bunun için menu.xml üzerinden aşağıdaki düzenlemeyi yapmanız gerekir.

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

<item
    android:id="@+id/optionsMenuFragment"
    android:menuCategory="secondary"
    android:title="Options Menu Item" />
</menu>

Gördüğünüz gibi bu işlemi aşağıdaki eklememiz ile gerçekleştirmiş olduk.

android:menuCategory="secondary"

Last updated