Menü ekleme

Oluşturma yöntemini deneyin
Android için önerilen kullanıcı arayüzü araç seti Jetpack Compose'dur. Oluşturma'da nasıl bileşen ekleyeceğinizi öğrenin.

Menüler, birçok uygulama türünde yaygın bir kullanıcı arayüzü bileşenidir. Tanıdık ve tutarlı bir kullanıcı deneyimi sunmak için Menu API'lerini kullanarak etkinliklerinizde kullanıcı işlemlerini ve diğer seçenekleri gösterin.

Taşma menüsü örneğini gösteren bir resim
Şekil 1. Simge dokunuşuyla tetiklenen ve taşma menüsü simgesinin altında görünen bir menü.

Bu belgede, Android'in tüm sürümlerinde üç temel menü veya işlem sunumu türünün nasıl oluşturulacağı gösterilmektedir:

Seçenekler menüsü ve uygulama çubuğu
Seçenekler menüsü, bir etkinlik için birincil menü öğesi koleksiyonudur. "Arama", "E-posta oluştur" ve "Ayarlar" gibi uygulama üzerinde genel etkisi olan işlemleri buraya yerleştirirsiniz.

Seçenek menüsü oluşturma bölümüne bakın.

Bağlam menüsü ve bağlamsal işlem modu
İçerik menüsü, kullanıcı bir öğeye dokunup basılı tuttuğunda görünen yüzen bir menü Seçilen içeriği veya bağlam çerçevesini etkileyen işlemleri sağlar.

Bağlamsal işlem modu, seçili içeriği etkileyen işlem öğelerini ekranın üst kısmındaki bir çubuğunda gösterir ve kullanıcının birden fazla öğe seçmesine olanak tanır.

İçerik menüsü oluşturma bölümüne bakın.

Pop-up menü
Pop-up menü, menüyü çağıran görünüme sabitlenmiş öğelerin dikey bir listesini gösterir. Belirli bir içerikle ilgili çok sayıda işlem sunmak veya bir komutun ikinci kısmı için seçenekler sunmak için kullanışlıdır. Pop-up menüsündeki işlemler, ilgili içeriği doğrudan etkilemez. Bağlamsal işlemler bunun içindir. Pop-up menü, etkinliğinizdeki içerik bölgeleriyle ilgili genişletilmiş işlemler içindir.

Pop-up menü oluşturma bölümüne bakın.

XML'de menü tanımlama

Android, tüm menü türleri için menü öğelerini tanımlamak üzere standart bir XML biçimi sağlar. Etkinliğinizin kodunda bir menü oluşturmak yerine, bir XML menü kaynağında bir menü ve tüm öğelerini tanımlayın. Ardından, menü kaynağını etkinliğinizde veya parçanızda Menu nesnesi olarak yükleyerek genişletebilirsiniz.

Menü kaynağı kullanmak aşağıdaki nedenlerden dolayı iyi bir uygulamadır:

  • XML'de menü yapısını görselleştirmek daha kolaydır.
  • Menünün içeriğini uygulamanızın davranış kodundan ayırır.
  • Uygulama kaynakları çerçevesinden yararlanarak farklı platform sürümleri, ekran boyutları ve diğer yapılandırmalar için alternatif menü yapılandırmaları oluşturmanıza olanak tanır.

Menü tanımlamak için projenizin res/menu/ dizininde bir XML dosyası oluşturun ve menüyü aşağıdaki öğelerle oluşturun:

<menu>
Menü öğelerinin kapsayıcısı olan bir Menu tanımlar. <menu> öğesi, dosyanın kök düğümü olmalıdır ve bir veya daha fazla <item> ve <group> öğesi barındırabilir.
<item>
Bir menüdeki tek bir öğeyi temsil eden bir MenuItem oluşturur. Bu öğe, alt menü oluşturmak için iç içe yerleştirilmiş bir <menu> öğesi içerebilir.
<group>
<item> öğeleri için isteğe bağlı, görünmez bir kapsayıcıdır. Menü öğelerini, etkin durum ve görünürlük gibi özellikleri paylaşacak şekilde kategorilere ayırmanıza olanak tanır. Daha fazla bilgi için Menü grubu oluşturma bölümüne bakın.

game_menu.xml adlı örnek bir menü aşağıda verilmiştir:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/new_game"
          android:icon="@drawable/ic_new_game"
          android:title="@string/new_game"
          app:showAsAction="ifRoom"/>
    <item android:id="@+id/help"
          android:icon="@drawable/ic_help"
          android:title="@string/help" />
</menu>

<item> öğesi, bir öğenin görünümünü ve davranışını tanımlamak için kullanabileceğiniz çeşitli özellikleri destekler. Önceki menüdeki öğeler aşağıdaki özellikleri içerir:

android:id
Öğeye özgü bir kaynak kimliğidir. Kullanıcı öğeyi seçtiğinde uygulamanın öğeyi tanımasına olanak tanır.
android:icon
Öğenin simgesi olarak kullanılacak bir çizilebilir öğeye referans.
android:title
Öğenin başlığı olarak kullanılacak bir dizeye referans.
android:showAsAction
Bu öğenin uygulama çubuğunda ne zaman ve nasıl işlem öğesi olarak görüneceğine dair spesifikasyon.

Bunlar, kullandığınız en önemli özelliklerdir ancak daha birçok özellik mevcuttur. Desteklenen tüm özellikler hakkında bilgi edinmek için Menü kaynağı dokümanlarına bakın.

Bir <item> öğesinin alt öğesi olarak <menu> öğesi ekleyerek herhangi bir menüdeki bir öğeye alt menü ekleyebilirsiniz. Alt menüler, uygulamanızda konulara göre düzenlenebilecek çok sayıda işlev olduğunda kullanışlıdır. Örneğin, PC uygulamasının menü çubuğundaki Dosya, Düzenle ve Görüntüle gibi öğeler alt menü olarak kullanılabilir. Aşağıdaki örneğe bakın:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/file"
          android:title="@string/file" >
        <!-- "file" submenu -->
        <menu>
            <item android:id="@+id/create_new"
                  android:title="@string/create_new" />
            <item android:id="@+id/open"
                  android:title="@string/open" />
        </menu>
    </item>
</menu>

Menüyü etkinliğinizde kullanmak için MenuInflater.inflate() kullanarak XML kaynağını programlanabilir bir nesneye dönüştürerek menü kaynağını _şişirin_. Aşağıdaki bölümlerde, her menü türü için bir menünün nasıl oluşturulacağı gösterilmektedir.

Seçenekler menüsü oluşturma

Şekil 1'de gösterilen gibi seçenekler menüsüne, mevcut etkinlik bağlamıyla alakalı işlemler ve diğer seçenekler ("Arama", "E-posta oluştur" ve "Ayarlar" gibi) eklersiniz.

Google E-Tablolar uygulamasının uygulama çubuğunu gösteren resim
Şekil 2. İşlem taşma düğmesi dahil olmak üzere çeşitli düğmeleri gösteren Google E-Tablolar uygulaması.

Seçenekler menüsü için öğeleri Activity alt sınıfınızdan veya Fragment alt sınıfından tanımlayabilirsiniz. Hem etkinliğiniz hem de parçalarınız seçenek menüsü için öğeler tanımlarsa öğeler kullanıcı arayüzünde birleştirilir. Önce etkinliğin öğeleri, ardından her bir parçanın öğeleri (parçaların etkinliğe eklenme sırasına göre) gösterilir. Gerekirse taşımanız gereken her <item> öğesinde android:orderInCategory özelliğini kullanarak menü öğelerini yeniden sıralayabilirsiniz.

Bir etkinlik için seçenekler menüsünü belirtmek üzere onCreateOptionsMenu() değerini geçersiz kılın. Parçalar kendi onCreateOptionsMenu() geri çağırma işlevlerini sağlar. Bu yöntemde, XML'de tanımlanan menü kaynağınızı geri çağırma işlevinde sağlanan Menu içine şişirebilirsiniz. Bu durum aşağıdaki örnekte gösterilmektedir:

Kotlin

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

Java

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.game_menu, menu);
    return true;
}

Ayrıca add() ile menü öğeleri ekleyebilir ve findItem() ile öğeleri alıp MenuItem API'leriyle özelliklerini düzeltebilirsiniz.

Tıklama etkinliklerini işleme

Kullanıcı, uygulama çubuğundaki işlem öğeleri de dahil olmak üzere seçenekler menüsünden bir öğe seçtiğinde sistem, etkinliğinizin onOptionsItemSelected() yöntemini çağırır. Bu yöntem, seçili MenuItem değerini iletir. Öğeyi tanımlamak için getItemId() yöntemini çağırabilirsiniz. Bu yöntem, menü kaynağındaki android:id özelliğiyle tanımlanan veya add() yöntemine verilen bir tam sayı ile menü öğesinin benzersiz kimliğini döndürür. Uygun işlemi gerçekleştirmek için bu kimliği bilinen menü öğeleriyle eşleştirebilirsiniz.

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    // Handle item selection.
    return when (item.itemId) {
        R.id.new_game -> {
            newGame()
            true
        }
        R.id.help -> {
            showHelp()
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle item selection.
    switch (item.getItemId()) {
        case R.id.new_game:
            newGame();
            return true;
        case R.id.help:
            showHelp();
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Bir menü öğesini başarıyla işlediğinizde true döndürün. Menü öğesini işlemezseniz onOptionsItemSelected() sınıfının üst sınıf uygulamasını çağırın. Varsayılan uygulama false değerini döndürür.

Etkinliğiniz parçalar içeriyorsa sistem önce etkinlik için onOptionsItemSelected(), ardından parçalar eklendikleri sırayla her bir parça için true döndürülene veya tüm parçalar çağrılana kadar çağrı yapar.

Çalışma zamanında menü öğelerini değiştirme

Sistem onCreateOptionsMenu() işlevini çağırdıktan sonra, doldurduğunuz Menu örneğini korur ve menü geçersiz kılınmadığı sürece onCreateOptionsMenu() işlevini tekrar çağırmaz. Ancak onCreateOptionsMenu() öğesini yalnızca ilk menü durumunu oluşturmak için kullanın, etkinlik yaşam döngüsü sırasında değişiklik yapmak için kullanmayın.

Seçenekler menüsünü etkinlik yaşam döngüsü sırasında gerçekleşen etkinliklere göre değiştirmek istiyorsanız bunu onPrepareOptionsMenu() yönteminde yapabilirsiniz. Bu yöntem, Menu nesnesini şu anda mevcut olduğu şekilde iletir. Böylece, öğe ekleme, kaldırma veya devre dışı bırakma gibi işlemler yaparak nesneyi değiştirebilirsiniz. Parçalar ayrıca bir onPrepareOptionsMenu() geri çağırma işlevi de sağlar.

Menü öğeleri uygulama çubuğunda gösterildiğinde seçenekler menüsünün her zaman açık olduğu kabul edilir. Bir etkinlik gerçekleştiğinde ve menü güncellemesi yapmak istediğinizde, sistemin onPrepareOptionsMenu()'u aramasını istemek için invalidateOptionsMenu()'ü arayın.

Bağlama dayalı menü oluşturma

Kayan içerik menüsünü gösteren resim
Şekil 3. Kayan içerik menüsü.

Bağlam menüsü, kullanıcı arayüzündeki belirli bir öğeyi veya bağlam çerçevesini etkileyen işlemler sunar. Herhangi bir görünüm için içerik menüsü sağlayabilirsiniz ancak içerik menüleri en çok RecylerView veya kullanıcının her öğe üzerinde doğrudan işlem gerçekleştirebildiği diğer görünüm koleksiyonlarındaki öğeler için kullanılır.

Bağlama dayalı işlemler sağlamanın iki yolu vardır:

  • Yüzen içerik menüsünde. Kullanıcı, içerik menüsünü desteklediğini belirten bir görünüme dokunup basılı tuttuğunda menü, iletişim kutusuna benzer şekilde, menü öğelerinin yüzen bir listesi olarak görünür. Kullanıcılar, aynı anda bir öğe üzerinde bağlama dayalı işlem gerçekleştirebilir.
  • Bağlamsal işlem modunda. Bu mod, ActionMode sisteminin bir uygulamasıdır. Ekranın üst kısmında, seçili öğeleri etkileyen işlem öğelerini içeren bir bağlamsal işlem çubuğu(CAB) gösterir. Bu mod etkinken, uygulamanız destekliyorsa kullanıcılar birden fazla öğede aynı anda işlem yapabilir.

Not: Bağlam menüsü, öğe kısayollarını ve öğe simgelerini desteklemez.

Kayan içerik menüsü oluşturma

Yüzen bir içerik menüsü sağlamak için aşağıdakileri yapın:

  1. registerForContextMenu() işlevini çağırıp View parametresini ileterek içerik menüsünün ilişkili olduğu View öğesini kaydedin.

    Etkinliğiniz bir RecyclerView kullanıyorsa ve her öğenin aynı içerik menüsünü sağlamasını istiyorsanız RecyclerView öğesini registerForContextMenu() öğesine ileterek tüm öğeleri bir içerik menüsüne kaydedin.

  2. Activity veya Fragment'nizde onCreateContextMenu() yöntemini uygulayın.

    Kayıtlı görünüm bir dokun ve bas etkinliği aldığında sistem onCreateContextMenu() yönteminizi çağırır. Menü öğelerini burada tanımlarsınız. Genellikle aşağıdaki örnekte olduğu gibi bir menü kaynağını şişirirsiniz:

    Kotlin

        override fun onCreateContextMenu(menu: ContextMenu, v: View,
                                menuInfo: ContextMenu.ContextMenuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo)
            val inflater: MenuInflater = menuInflater
            inflater.inflate(R.menu.context_menu, menu)
        }
        

    Java

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                                        ContextMenuInfo menuInfo) {
            super.onCreateContextMenu(menu, v, menuInfo);
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.context_menu, menu);
        }
        

    MenuInflater içerik menüsünü bir menü kaynağından şişirmenize olanak tanır. Geri çağırma yöntemi parametreleri, kullanıcının seçtiği View öğesini ve seçilen öğe hakkında ek bilgi sağlayan bir ContextMenu.ContextMenuInfo nesnesi içerir. Etkinliğinizin her biri farklı bir bağlam menüsü sunan birkaç görünümü varsa hangi bağlam menüsünün oluşturulacağını belirlemek için bu parametreleri kullanabilirsiniz.

  3. Aşağıdaki örnekte gösterildiği gibi onContextItemSelected() değerini uygulayın. Kullanıcı bir menü öğesi seçtiğinde sistem, uygun işlemi gerçekleştirebilmeniz için bu yöntemi çağırır.

    Kotlin

        override fun onContextItemSelected(item: MenuItem): Boolean {
            val info = item.menuInfo as AdapterView.AdapterContextMenuInfo
            return when (item.itemId) {
                R.id.edit -> {
                    editNote(info.id)
                    true
                }
                R.id.delete -> {
                    deleteNote(info.id)
                    true
                }
                else -> super.onContextItemSelected(item)
            }
        }
        

    Java

        @Override
        public boolean onContextItemSelected(MenuItem item) {
            AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
            switch (item.getItemId()) {
                case R.id.edit:
                    editNote(info.id);
                    return true;
                case R.id.delete:
                    deleteNote(info.id);
                    return true;
                default:
                    return super.onContextItemSelected(item);
            }
        }
        

    getItemId() yöntemi, seçili menü öğesinin kimliğini sorgulayarak android:id özelliğini kullanarak XML'deki her menü öğesine atar. Bu işlem XML'de menü tanımlama bölümünde gösterilmiştir.

    Bir menü öğesini başarıyla işlediğinizde true döndürün. Menü öğesini işlemezseniz menü öğesini üst sınıf uygulamasına iletin. Etkinliğiniz parça içeriyorsa etkinlik önce bu geri çağırma işlevini alır. İşlenmemiş durumdayken üst sınıfı çağıran sistem, true veya false döndürülene kadar her bir parçanın eklenme sırasına göre her bir parçadaki ilgili geri çağırma yöntemine etkinliği tek tek iletir. Activity ve android.app.Fragment için varsayılan uygulamalar false döndürür. Bu nedenle, işlenmemiş durumlarda her zaman üst sınıfı çağırın.

Bağlamsal işlem modunu kullanma

Bağlamsal işlem modu, kullanıcı etkileşimini bağlamsal işlemler gerçekleştirmeye odaklayan ActionMode'ün sistem uygulamasıdır. Kullanıcı bir öğe seçerek bu modu etkinleştirdiğinde, ekranın üst kısmında kullanıcının seçili öğelerde yapabileceği işlemleri gösteren bir bağlamsal işlem çubuğu görünür. Bu mod etkinken kullanıcı, uygulamanız bunu destekliyorsa birden fazla öğe seçebilir, öğelerin seçimini kaldırabilir ve etkinlik içinde gezinmeye devam edebilir. Kullanıcı tüm öğelerin seçimini kaldırdığında, Geri düğmesine veya çubuğun sol tarafındaki Bitti işlemine dokunduğunda işlem modu devre dışı bırakılır ve bağlama dayalı işlem çubuğu kaybolur.

Bağlamsal işlemler sağlayan görünümlerde, genellikle aşağıdaki iki durumdan biri veya her ikisi gerçekleştiğinde bağlamsal işlem modunu çağırırsınız:

  • Kullanıcı, görünüme dokunup basılı tutar.
  • Kullanıcı, görünümde bir onay kutusunu veya benzer bir kullanıcı arayüzü bileşenini seçer.

Uygulamanızın bağlama dayalı işlem modunu nasıl çağıracağı ve her işlem için davranışı nasıl tanımlayacağı tasarımınıza bağlıdır. İki tasarım vardır:

  • Ayrı ayrı, rastgele görüntülemelerde bağlamsal işlemler için.
  • RecyclerView içindeki öğe gruplarında toplu bağlama dayalı işlemler için kullanılır. Kullanıcının birden fazla öğe seçmesine ve bunların hepsinde bir işlem yapmasına olanak tanır.

Aşağıdaki bölümlerde, ilk senaryo için gereken kurulum açıklanmaktadır.

Bağlamsal işlem modunu tek tek görüntülemeler için etkinleştirme

Bağlamsal işlem modunu yalnızca kullanıcı belirli görünümleri seçtiğinde çağırmak istiyorsanız aşağıdakileri yapın:

  1. ActionMode.Callback arayüzünü aşağıdaki örnekte gösterildiği gibi uygulayın. Geri çağırma yöntemlerinde, bağlama dayalı işlem çubuğuyla ilgili işlemleri belirtebilir, işlem öğelerindeki tıklama etkinliklerine yanıt verebilir ve işlem modu için diğer yaşam döngüsü etkinliklerini yönetebilirsiniz.

    Kotlin

        private val actionModeCallback = object : ActionMode.Callback {
            // Called when the action mode is created. startActionMode() is called.
            override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
                // Inflate a menu resource providing context menu items.
                val inflater: MenuInflater = mode.menuInflater
                inflater.inflate(R.menu.context_menu, menu)
                return true
            }
    
            // Called each time the action mode is shown. Always called after
            // onCreateActionMode, and might be called multiple times if the mode
            // is invalidated.
            override fun onPrepareActionMode(mode: ActionMode, menu: Menu): Boolean {
                return false // Return false if nothing is done
            }
    
            // Called when the user selects a contextual menu item.
            override fun onActionItemClicked(mode: ActionMode, item: MenuItem): Boolean {
                return when (item.itemId) {
                    R.id.menu_share -> {
                        shareCurrentItem()
                        mode.finish() // Action picked, so close the CAB.
                        true
                    }
                    else -> false
                }
            }
    
            // Called when the user exits the action mode.
            override fun onDestroyActionMode(mode: ActionMode) {
                actionMode = null
            }
        }
        

    Java

        private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
    
            // Called when the action mode is created. startActionMode() is called.
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                // Inflate a menu resource providing context menu items.
                MenuInflater inflater = mode.getMenuInflater();
                inflater.inflate(R.menu.context_menu, menu);
                return true;
            }
    
            // Called each time the action mode is shown. Always called after
            // onCreateActionMode, and might be called multiple times if the mode
            // is invalidated.
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return false; // Return false if nothing is done.
            }
    
            // Called when the user selects a contextual menu item.
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
               switch (item.getItemId()) {
                    case R.id.menu_share:
                        shareCurrentItem();
                        mode.finish(); // Action picked, so close the CAB.
                        return true;
                    default:
                        return false;
                }
            }
    
            // Called when the user exits the action mode.
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                actionMode = null;
            }
        };
        

    Bu etkinlik geri çağırma işlevleri, seçenekler menüsü içinki geri çağırma işlevleriyle neredeyse aynıdır. Tek fark, bunların her birinin etkinlikle ilişkili ActionMode nesnesini de iletmesidir. CAB'de çeşitli değişiklikler yapmak için ActionMode API'lerini kullanabilirsiniz. Örneğin, başlığı ve alt başlığı setTitle() ve setSubtitle() ile düzeltebilirsiniz. Bu, kaç öğenin seçildiğini belirtmek için kullanışlıdır.

    Önceki örnekte, işlem modu yok edildiğinde actionMode değişkeni null olarak ayarlanır. Bir sonraki adımda, üye değişkeninin nasıl başlatıldığını ve etkinliğinize veya parçanıza kaydedilmesinin nasıl yararlı olabileceğini öğrenin.

  2. Kullanıcı görünüme dokunup basılı tuttuğunda çubuğu göstermek istediğinizde startActionMode() metodunu çağırın.

    Kotlin

        someView.setOnLongClickListener { view ->
            // Called when the user performs a touch & hold on someView.
            when (actionMode) {
                null -> {
                    // Start the CAB using the ActionMode.Callback defined earlier.
                    actionMode = activity?.startActionMode(actionModeCallback)
                    view.isSelected = true
                    true
                }
                else -> false
            }
        }
        

    Java

        someView.setOnLongClickListener(new View.OnLongClickListener() {
            // Called when the user performs a touch & hold on someView.
            public boolean onLongClick(View view) {
                if (actionMode != null) {
                    return false;
                }
    
                // Start the CAB using the ActionMode.Callback defined earlier.
                actionMode = getActivity().startActionMode(actionModeCallback);
                view.setSelected(true);
                return true;
            }
        });
        

    startActionMode() işlevini çağırdığınızda sistem, oluşturulan ActionMode değerini döndürür. Bunu bir üye değişkenine kaydederek diğer etkinliklere yanıt olarak bağlama dayalı işlem çubuğunda değişiklik yapabilirsiniz. Önceki örnekte, işlem modunu başlatmadan önce üyenin null olup olmadığını kontrol ederek ActionMode örneğinin zaten etkinse yeniden oluşturulmamasını sağlamak için ActionMode kullanılır.

Pop-up menü oluşturma

Gmail uygulamasında sağ üstteki üç nokta simgesine sabitlenmiş bir pop-up menüyü gösteren resim.
Şekil 4. Gmail uygulamasında, sağ üst köşedeki taşma düğmesine sabitlenmiş bir pop-up menü.

PopupMenu, View'a sabitlenmiş bir modal menüdür. Yer varsa sabit görünümün altında, yoksa görünümün üstünde görünür. Aşağıdakiler için kullanışlıdır:

  • Şekil 4'te gösterilen Gmail e-posta üstbilgileri gibi belirli içeriklerle ilgili işlemler için taşma stilinde bir menü sağlama
  • Komut cümlesinin ikinci bir bölümünü sağlamak (ör. farklı Ekle seçenekleri içeren bir pop-up menüsü oluşturan Ekle işaretli bir düğme).
  • Kalıcı bir seçim tutmayan Spinner benzeri bir menü sunma.

Menünüzü XML olarak tanımlarsanız pop-up menüyü şu şekilde gösterebilirsiniz:

  1. Bir PopupMenu'ü, mevcut uygulamayı Context ve menünün sabitlendiği View öğesini alan kurucusuyla oluşturun.
  2. Menü kaynağınızı PopupMenu.getMenu() tarafından döndürülen Menu nesnesine genişletmek için MenuInflater öğesini kullanın.
  3. Şu numaraya telefon et: PopupMenu.show().

Örneğin, pop-up menü gösteren bir düğme:

<ImageButton
    android:id="@+id/dropdown_menu"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/descr_overflow_button"
    android:src="@drawable/arrow_drop_down" />

Ardından etkinlik, pop-up menüsünü aşağıdaki gibi gösterebilir:

Kotlin

findViewById<ImageButton>(R.id.dropdown_menu).setOnClickListener {
    val popup = PopupMenu(this, it)
    val inflater: MenuInflater = popup.menuInflater
    inflater.inflate(R.menu.actions, popup.menu)
    popup.show()
}

Java

findViewById(R.id.dropdown_menu).setOnClickListener(v -> {
    PopupMenu popup = new PopupMenu(this, v);
    popup.getMenuInflater().inflate(R.menu.actions, popup.getMenu());
    popup.show();
});

Kullanıcı bir öğe seçtiğinde veya menü alanının dışına dokunduğunda menü kapatılır. PopupMenu.OnDismissListener kullanarak kapatma etkinliğini dinleyebilirsiniz.

Tıklama etkinliklerini işleme

Kullanıcı bir menü öğesi seçtiğinde bir işlem gerçekleştirmek için PopupMenu.OnMenuItemClickListener arabirimini uygulayın ve setOnMenuItemclickListener() işlevini çağırarak PopupMenu'inize kaydedin. Kullanıcı bir öğe seçtiğinde sistem, arayüzünüzdeki onMenuItemClick() geri çağırma işlevini çağırır.

Bu durum aşağıdaki örnekte gösterilmektedir:

Kotlin

fun showMenu(v: View) {
    PopupMenu(this, v).apply {
        // MainActivity implements OnMenuItemClickListener.
        setOnMenuItemClickListener(this@MainActivity)
        inflate(R.menu.actions)
        show()
    }
}

override fun onMenuItemClick(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.archive -> {
            archive(item)
            true
        }
        R.id.delete -> {
            delete(item)
            true
        }
        else -> false
    }
}

Java

public void showMenu(View v) {
    PopupMenu popup = new PopupMenu(this, v);

    // This activity implements OnMenuItemClickListener.
    popup.setOnMenuItemClickListener(this);
    popup.inflate(R.menu.actions);
    popup.show();
}

@Override
public boolean onMenuItemClick(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.archive:
            archive(item);
            return true;
        case R.id.delete:
            delete(item);
            return true;
        default:
            return false;
    }
}

Menü grubu oluşturma

Menü grubu, belirli özellikleri paylaşan bir menü öğeleri koleksiyonudur. Gruplarla şunları yapabilirsiniz:

  • setGroupVisible() simgesini kullanarak tüm öğeleri gösterin veya gizleyin.
  • setGroupEnabled() simgesini kullanarak tüm öğeleri etkinleştirin veya devre dışı bırakın.
  • Tüm öğelerin işaretlenebilir olup olmadığını setGroupCheckable() kullanarak belirtin.

Menü kaynağınızdaki bir <group> öğesinin içine <item> öğeleri yerleştirerek veya add() yöntemiyle bir grup kimliği belirterek grup oluşturabilirsiniz.

Bir grup içeren menü kaynağı örneğini aşağıda bulabilirsiniz:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/menu_save"
          android:icon="@drawable/menu_save"
          android:title="@string/menu_save" />
    <!-- menu group -->
    <group android:id="@+id/group_delete">
        <item android:id="@+id/menu_archive"
              android:title="@string/menu_archive" />
        <item android:id="@+id/menu_delete"
              android:title="@string/menu_delete" />
    </group>
</menu>

Gruptaki öğeler ilk öğeyle aynı düzeyde görünür. Menüdeki üç öğe de kardeştir. Ancak grup kimliğine referans vererek ve önceki yöntemleri kullanarak gruptaki iki öğenin özelliklerini değiştirebilirsiniz. Sistem, gruplandırılmış öğeleri de hiçbir zaman ayırmaz. Örneğin, her öğe için android:showAsAction="ifRoom" bildirirseniz her ikisi de işlem çubuğunda veya işlem taşmasında görünür.

İşaretlenebilecek menü öğeleri kullanma

Şekil 5. İşaretlenebilecek öğelerin bulunduğu bir alt menü.

Menüler, bağımsız seçenekler için onay kutusu veya birbirini hariç tutan seçenek grupları için radyo düğmeleri kullanarak seçenekleri etkinleştirmek ve devre dışı bırakmak için bir arayüz olarak yararlı olabilir. Şekil 5'te, radyo düğmeleriyle işaretlenebilen öğelerin bulunduğu bir alt menü gösterilmektedir.

<item> öğesindeki android:checkable özelliğini kullanarak tek tek menü öğeleri için veya <group> öğesindeki android:checkableBehavior özelliğini kullanarak bir grubun tamamı için işaretlenebilir davranışı tanımlayabilirsiniz. Örneğin, bu menü grubundaki tüm öğeler radyo düğmesiyle işaretlenebilir:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item android:id="@+id/red"
              android:title="@string/red" />
        <item android:id="@+id/blue"
              android:title="@string/blue" />
    </group>
</menu>

android:checkableBehavior özelliği aşağıdakilerden birini kabul eder:

single
Gruptaki yalnızca bir öğe işaretlenebilir. Bu durumda radyo düğmeleri kullanılır.
all
Tüm öğeler işaretlenebilir. Bu durumda onay kutuları gösterilir.
none
Hiçbir öğe işaretlenemez.

<item> öğesindeki android:checked özelliğini kullanarak bir öğeye varsayılan olarak işaretli bir durum uygulayabilir ve bunu setChecked() yöntemiyle kodda değiştirebilirsiniz.

İşaretlenebilecek bir öğe seçildiğinde sistem, ilgili öğe seçildiğinde geri çağırma yönteminizi (ör. onOptionsItemSelected()) çağırır. Onay kutusu veya radyo düğmesi durumunu otomatik olarak değiştirmediğinden, onay kutusunun durumunu buradan ayarlarsınız. isChecked() ile öğenin mevcut durumunu (kullanıcı tarafından seçilmeden önceki durumu) sorgulayabilir ve ardından setChecked() ile işaretli durumu ayarlayabilirsiniz. Bu durum aşağıdaki örnekte gösterilmektedir:

Kotlin

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
        R.id.vibrate, R.id.dont_vibrate -> {
            item.isChecked = !item.isChecked
            true
        }
        else -> super.onOptionsItemSelected(item)
    }
}

Java

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.vibrate:
        case R.id.dont_vibrate:
            if (item.isChecked()) item.setChecked(false);
            else item.setChecked(true);
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

İşaretli durumu bu şekilde ayarlamazsanız kullanıcı seçtiğinde onay kutusunun veya radyo düğmesinin görünür durumu değişmez. Durumu ayarlarken etkinlik, öğenin işaretli durumunu korur. Böylece kullanıcı daha sonra menüyü açtığında ayarladığınız işaretli durum görünür.

Bir amaca göre menü öğeleri ekleme

Bazen bir menü öğesinin, uygulamanızdaki veya başka bir uygulamadaki bir etkinliği başlatmak için Intent kullanmasını istersiniz. Kullanmak istediğiniz niyeti bildiğinizde ve niyeti başlatan belirli bir menü öğeniz olduğunda, onOptionsItemSelected() geri çağırma gibi uygun öğe seçildiğinde geri çağırma yöntemi sırasında startActivity() ile niyeti yürütebilirsiniz.

Ancak kullanıcının cihazında niyeti işleyen bir uygulama bulunduğundan emin değilseniz niyeti çağıran bir menü öğesi eklemek, niyet bir etkinliğe çözümlenemediği için çalışmayan bir menü öğesine neden olabilir. Android, bu sorunu çözmek için cihazda intent'inizi işleyen etkinlikler bulduğunda menünüze dinamik olarak menü öğeleri eklemenize olanak tanır.

Amaç kabul eden mevcut etkinliklere göre menü öğeleri eklemek için aşağıdakileri yapın:

  1. CATEGORY_ALTERNATIVE veya CATEGORY_SELECTED_ALTERNATIVE kategorisini ya da her ikisini birden ve diğer koşulları içeren bir intent tanımlayın.
  2. Menu.addIntentOptions() numaralı telefonu arayın. Android daha sonra, intent'i gerçekleştirebilecek uygulamaları arar ve bunları menünüze ekler.

Amacın karşılandığı yüklü uygulama yoksa menü öğesi eklenmez.

Bu durum aşağıdaki örnekte gösterilmektedir:

Kotlin

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    super.onCreateOptionsMenu(menu)

    // Create an Intent that describes the requirements to fulfill, to be
    // included in the menu. The offering app must include a category value
    // of Intent.CATEGORY_ALTERNATIVE.
    val intent = Intent(null, dataUri).apply {
        addCategory(Intent.CATEGORY_ALTERNATIVE)
    }

    // Search and populate the menu with acceptable offering apps.
    menu.addIntentOptions(
            R.id.intent_group,  // Menu group to which new items are added.
            0,                  // Unique item ID (none).
            0,                  // Order for the items (none).
            this.componentName, // The current activity name.
            null,               // Specific items to place first (none).
            intent,             // Intent created above that describes the requirements.
            0,                  // Additional flags to control items (none).
            null)               // Array of MenuItems that correlate to specific items (none).

    return true
}

Java

@Override
public boolean onCreateOptionsMenu(Menu menu){
    super.onCreateOptionsMenu(menu);

    // Create an Intent that describes the requirements to fulfill, to be
    // included in the menu. The offering app must include a category value
    // of Intent.CATEGORY_ALTERNATIVE.
    Intent intent = new Intent(null, dataUri);
    intent.addCategory(Intent.CATEGORY_ALTERNATIVE);

    // Search and populate the menu with acceptable offering apps.
    menu.addIntentOptions(
         R.id.intent_group,         // Menu group to which new items are added.
         0,                         // Unique item ID (none).
         0,                         // Order for the items (none).
         this.getComponentName(),   // The current activity name.
         null,                      // Specific items to place first (none).
         intent,                    // Intent created above that describes the requirements.
         0,                         // Additional flags to control items (none).
         null);                     // Array of MenuItems that correlate to specific items (none).

    return true;
}

Tanımlanan intent ile eşleşen bir intent filtresi sağlayan her etkinlik için, intent filtresinin android:label bölümündeki değer menü öğesi başlığı olarak, uygulama simgesi ise menü öğesi simgesi olarak kullanılarak bir menü öğesi eklenir. addIntentOptions() yöntemi, eklenen menü öğelerinin sayısını döndürür.

Etkinliğinizin diğer menülere eklenmesine izin verme

Uygulamanızın diğer uygulamaların menüsüne eklenmesi için etkinliğinizin hizmetlerini diğer uygulamalara sunabilirsiniz. Böylece, daha önce açıklanan rolleri tersine çevirmiş olursunuz.

Diğer uygulama menülerine dahil edilmek için her zamanki gibi bir intent filtresi tanımlayın ancak intent filtresi kategorisi için CATEGORY_ALTERNATIVE veya CATEGORY_SELECTED_ALTERNATIVE değerlerini ya da her ikisini birden ekleyin. Bu durum aşağıdaki örnekte gösterilmektedir:

<intent-filter label="@string/resize_image">
    ...
    <category android:name="android.intent.category.ALTERNATIVE" />
    <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
    ...
</intent-filter>

Intent'ler ve intent filtreleri başlıklı makalede intent filtresi yazma hakkında daha fazla bilgi edinin.