Menü ekleme

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

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

Taşma menüsü örneğini gösteren bir resim
Şekil 1. Taşma menüsü simgesinin altında görünen, simgeye dokunarak tetiklenen 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 etkinliğe ait menü öğelerinin birincil koleksiyonudur. "Arama", "E-posta oluştur" ve "Ayarlar" gibi uygulama üzerinde genel etkisi olan işlemleri buraya yerleştirirsiniz.

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

Bağlam menüsü ve bağlamsal işlem modu
Bağlam menüsü, kullanıcının bir öğeye dokunup basılı tutmasıyla görünen kayan bir menüdür. Seçili içeriği veya bağlam çerçevesini etkileyen işlemler sunar.

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

Bağlam 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ş dikey bir öğe listesi gösterir. Belirli bir içerikle ilgili çok sayıda işlem sunmak veya bir komutun ikinci bölümü için seçenekler sağlamak amacıyla kullanılabilir. Pop-up menüdeki işlemler, ilgili içeriği doğrudan etkilemez. Bunun için içerik menüsündeki işlemler kullanılır. Bunun yerine, 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 menü oluşturmak yerine bir menü ve tüm öğelerini bir XML menü kaynağında tanımlayın. Ardından, menü kaynağını şişirebilir (etkinliğinize veya parçanıza Menu nesnesi olarak yükleyebilirsiniz).

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

  • XML'deki menü yapısını görselleştirmek daha kolaydır.
  • Menü 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
öğesini tanımlar.Menu <menu> öğesi, dosyanın kök düğümü olmalı ve bir veya daha fazla <item> ile <group> öğesi içerebilir.
<item>
Bir menüdeki tek bir öğeyi temsil eden 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 kategorize etmenize olanak tanır. Daha fazla bilgi için Menü grubu oluşturma bölümüne bakın.

game_menu.xml adlı bir menü örneğini aşağıda görebilirsiniz:

<?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ü olan ve kullanıcı öğeyi seçtiğinde uygulamanın öğeyi tanımasını sağlayan bir kaynak kimliği.
android:icon
Öğenin simgesi olarak kullanılacak bir çizilebilir öğeye referans.
android:title
Öğenin başlığı olarak kullanılacak bir dizeye yapılan referans.
android:showAsAction
Bu öğenin, uygulama çubuğunda işlem öğesi olarak ne zaman ve nasıl 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.

Herhangi bir menüdeki öğeye, <menu> öğesini <item> öğesinin alt öğesi olarak ekleyerek alt menü ekleyebilirsiniz. Alt menüler, uygulamanızda konular halinde düzenlenebilecek çok sayıda işlev olduğunda (ör. bir PC uygulamasının menü çubuğundaki Dosya, Düzenle ve Görünüm gibi öğeler) kullanışlıdır. 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>

Etkinliğinizde menüyü kullanmak için menü kaynağını _genişletin_ ve MenuInflater.inflate() kullanarak XML kaynağını programlanabilir bir nesneye dönüştürün. Aşağıdaki bölümlerde, her menü türü için menünün nasıl genişletileceği gösterilmektedir.

Seçenekler menüsü oluşturma

Şekil 1'de gösterilene benzer bir seçenekler menüsünde, geçerli etkinlik bağlamıyla alakalı işlemler ve diğer seçenekler yer alır. Örneğin, "Ara", "E-posta oluştur" ve "Ayarlar" gibi.

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

Seçenekler menüsündeki öğeleri, Activity Fragment alt sınıfınızdan veya bir alt sınıftan bildirebilirsiniz. Hem etkinliğiniz hem de parçalarınız seçenekler menüsü için öğeler bildiriyorsa öğ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örünür. Gerekirse menü öğelerini, taşımak istediğiniz her <item> için android:orderInCategory özelliğiyle 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şlevini sağlar. Bu yöntemde, XML'de tanımlanan menü kaynağınızı geri çağırmada sağlanan Menu içine genişletebilirsiniz. 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() kullanarak menü öğeleri ekleyebilir ve findItem() ile öğeleri alarak MenuItem API'leri ile özelliklerini revize edebilirsiniz.

Tıklama etkinliklerini işleme

Kullanıcı, seçenekler menüsünden bir öğe (uygulama çubuğundaki işlem öğeleri dahil) seçtiğinde sistem, etkinliğinizin onOptionsItemSelected() yöntemini çağırır. Bu yöntem, MenuItem seçeneğini iletir. Öğeyi, getItemId() işlevini çağırarak tanımlayabilirsiniz. Bu işlev, menü kaynağındaki android:id özelliğiyle tanımlanan veya add() yöntemine verilen bir tam sayıyla tanımlanan menü öğesinin benzersiz kimliğini döndürür. Bu kimliği, bilinen menü öğeleriyle eşleştirerek uygun işlemi gerçekleş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 değerini döndürün. Menü öğesini işlememeyi tercih ederseniz onOptionsItemSelected() üst sınıf uygulamasını çağırın. Varsayılan uygulama false değerini döndürür.

Etkinliğinizde parçalar varsa sistem önce etkinlik için onOptionsItemSelected() işlevini, ardından parçalar eklenme sırasına göre her parça için onOptionsItemSelected() işlevini çağırır. Bu işlem, bir parça true değerini döndürene veya tüm parçalar çağrılana kadar devam eder.

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

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

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

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

Bağlamsal menü oluşturma

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

Bağlama duyarlı menü, 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 bağlam menüsü sağlayabilirsiniz ancak bunlar en çok RecylerView veya kullanıcının her öğe üzerinde doğrudan işlem yapabileceği diğer görünüm koleksiyonlarındaki öğeler için kullanılır.

Bağlama dayalı işlemler iki şekilde sağlanabilir:

  • Kayar içerik menüsünde. Kullanıcı, bağlam menüsü desteği bildiren bir görünümde dokunup basılı tutma işlemi yaptığında menü, iletişim kutusuna benzer şekilde kayan bir menü öğeleri listesi olarak görünür. Kullanıcılar, tek seferde bir öğe üzerinde bağlamsal işlem gerçekleştirebilir.
  • Bağlamsal işlem modunda Bu mod, seçili öğeleri etkileyen işlem öğeleriyle birlikte ekranın üst kısmında bağlama duyarlı işlem çubuğu(CAB) gösteren bir sistem uygulamasıdır.ActionMode Bu mod etkin olduğunda, uygulamanız destekliyorsa kullanıcılar aynı anda birden fazla öğede işlem yapabilir.

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

Kaydırma bağlam menüsü oluşturma

Kaydırma içerik menüsü sağlamak için aşağıdakileri yapın:

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

    Etkinliğinizde RecyclerView kullanılıyorsa ve her öğenin aynı bağlam menüsünü sağlamasını istiyorsanız RecyclerView öğesini registerForContextMenu()'ye ileterek tüm öğeleri bağlam menüsü için kaydedin.

  2. onCreateContextMenu() yöntemini Activity veya Fragment uygulamanızda uygulayın.

    Kayıtlı görünüm dokunma ve basılı tutma 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ı genişleterek tanımlarsınız:

    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 İçerik menüsünü bir menü kaynağında genişletmenize olanak tanır. Geri arama yöntemi parametreleri, kullanıcının seçtiği View ve seçilen öğe hakkında ek bilgiler sağlayan bir ContextMenu.ContextMenuInfo nesnesini içerir. Etkinliğinizde her biri farklı bir bağlam menüsü sağlayan birden fazla görünüm varsa hangi bağlam menüsünün genişletileceğini belirlemek için bu parametreleri kullanabilirsiniz.

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

    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çilen menü öğesinin kimliğini sorgular. Bu kimliği, XML'de menü tanımlama bölümünde gösterildiği gibi, XML'deki her menü öğesine android:id özelliğini kullanarak atarsınız.

    Bir menü öğesini başarıyla işlediğinizde true değerini döndürün. Menü öğesini işlemeyecekseniz menü öğesini üst sınıf uygulamasına iletin. Etkinliğiniz parçalar içeriyorsa bu geri çağırma önce etkinlik tarafından alınır. İşlenmeyen etkinlikler için üst sınıfı çağırdığınızda sistem, true veya false döndürülene kadar her bir parçayı eklendiği sırayla, her parçadaki ilgili geri çağırma yöntemine birer birer geçirir. Activity ve android.app.Fragment için varsayılan uygulamalar false değerini döndürür. Bu nedenle, işlenmeyen durumlarda her zaman üst sınıfı çağırın.

Bağlamsal işlem modunu kullanma

Bağlama dayalı işlem modu, kullanıcı etkileşimini bağlama dayalı işlemler yapmaya yönlendiren bir ActionMode sistem uygulamasıdır. Kullanıcı bir öğe seçerek bu modu etkinleştirdiğinde, seçilen öğelerde gerçekleştirebileceği işlemleri sunmak için ekranın üst kısmında bir bağlama özgü işlem çubuğu görünür. Bu mod etkinleştirildiğinde, uygulamanız destekliyorsa kullanıcı 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 dokunduğunda 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 bu iki etkinlikten 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 kutusu veya benzer bir kullanıcı arayüzü bileşeni seçer.

Uygulamanızın bağlamsal işlem modunu nasıl çağırdığı ve her işlemin davranışını nasıl tanımladığı, tasarımınıza bağlıdır. İki tasarım vardır:

  • Tek tek, rastgele görünümlerdeki bağlamsal işlemler için.
  • RecyclerView içindeki öğe gruplarında toplu bağlamsal işlemler için, kullanıcının birden fazla öğe seçmesine ve bunların hepsinde işlem yapmasına izin verilir.

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

Bağlamsal işlem modunu tek tek görünümler 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ğlamsal işlem çubuğunun işlemlerini belirtebilir, işlem öğelerindeki tıklama etkinliklerine yanıt verebilir ve işlem modu için diğer yaşam döngüsü etkinliklerini işleyebilirsiniz.

    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ğırmaları, seçenekler menüsündeki geri çağırmalarıyla neredeyse aynıdır. Tek fark, her birinin etkinlikle ilişkili ActionMode nesnesini de iletmesidir. ActionMode API'lerini kullanarak CAB'de çeşitli değişiklikler yapabilirsiniz. Örneğin, başlığı ve altyazıyı setTitle() ve setSubtitle() ile revize edebilirsiniz. Bu, kaç öğenin seçildiğini belirtmek için kullanışlıdır.

    Yukarıdaki örnek, işlem modu yok edildiğinde actionMode değişkenini null olarak ayarlar. Bir sonraki adımda, nasıl başlatıldığını ve üye değişkenini etkinliğinize veya parçanıza kaydetmenin nasıl faydalı olabileceğini görün.

  2. Arama startActionMode() Çubuğu göstermek istediğinizde (ör. kullanıcı görünüme dokunup basılı tuttuğunda) kullanı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() numaralı telefonu aradığı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ğlamsal işlem çubuğunda değişiklik yapabilirsiniz. Yukarıdaki örnekte, işlem modu başlatılmadan önce üyenin null olup olmadığı kontrol edilerek ActionMode örneğinin zaten etkinse yeniden oluşturulmaması için ActionMode kullanılır.

Pop-up menü oluşturma

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

PopupMenu, View öğesine sabitlenmiş bir modal menüdür. Yeterli alan varsa sabit görünümün altında, aksi takdirde üstünde görünür. Bu özellik aşağıdaki durumlarda kullanışlıdır:

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

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

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

Örneğin, aşağıda pop-up menü gösteren bir düğme yer almaktadır:

<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" />

Etkinlik daha sonra pop-up menüyü 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. Kapatma etkinliğini PopupMenu.OnDismissListener kullanarak dinleyebilirsiniz.

Tıklama etkinliklerini işleme

Kullanıcı bir menü öğesi seçtiğinde işlem gerçekleştirmek için PopupMenu.OnMenuItemClickListener arayüzünü uygulayın ve setOnMenuItemclickListener() işlevini çağırarak PopupMenu ile 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 menü öğelerinden oluşan bir koleksiyondur. Gruplarla şunları yapabilirsiniz:

  • setGroupVisible() simgesini kullanarak tüm öğeleri gösterme veya gizleme
  • setGroupEnabled() seçeneğini kullanarak tüm öğeleri etkinleştirin veya devre dışı bırakın.
  • Tüm öğelerin setGroupCheckable() kullanılarak işaretlenip işaretlenemeyeceğini belirtin.

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

Aşağıda, grup içeren bir menü kaynağı örneği verilmiştir:

<?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ş öğelerdir. Ancak, grup kimliğine referans vererek ve yukarıdaki yöntemleri kullanarak gruptaki iki öğenin özelliklerini değiştirebilirsiniz. Sistem, gruplandırılmış öğeleri hiçbir zaman ayırmaz. Örneğin, her öğe için android:showAsAction="ifRoom" beyan ederseniz her ikisi de işlem çubuğunda veya her ikisi de işlem taşmasında görünür.

İşaretlenebilir menü öğelerini kullanma

Şekil 5. İşaretlenebilir öğeler içeren bir alt menü.

Menü, seçenekleri açıp kapatmak için bir arayüz olarak kullanılabilir. Bağımsız seçenekler için onay kutusu, birbirini dışlayan seçenek grupları için ise radyo düğmeleri kullanılabilir. Şekil 5'te, radyo düğmeleriyle işaretlenebilen öğelerin bulunduğu bir alt menü gösterilmektedir.

<item> öğesindeki android:checkable özelliğiyle tek tek menü öğeleri için veya <group> öğesindeki android:checkableBehavior özelliğiyle bir grubun tamamı için işaretlenebilir davranışını 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
Gruptan yalnızca bir öğe işaretlenebilir. Bu durumda radyo düğmeleri gösterilir.
all
Tüm öğeler işaretlenebilir ve onay kutuları oluşturulabilir.
none
Öğe kontrol edilemiyor.

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

İşaretlenebilir bir öğe seçildiğinde sistem, onOptionsItemSelected() gibi ilgili öğe seçildi geri çağırma yönteminizi çağırır. Onay kutusu veya radyo düğmesi durumunu otomatik olarak değiştirmediğinden, onay kutusunun durumunu burada ayarlarsınız. Öğenin mevcut durumunu (kullanıcı tarafından seçilmeden önceki haliyle) isChecked() ile sorgulayabilir, ardından işaretli durumu setChecked() ile 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ı onay kutusunu veya radyo düğmesini seçtiğinde onay kutusunun ya da radyo düğmesinin görünür durumu değişmez. Durumu ayarladığınızda etkinlik, öğenin işaretli durumunu korur. Böylece, kullanıcı menüyü daha sonra açtığında ayarladığınız işaretli durum görünür.

Amaca göre menü öğeleri ekleme

Bazen bir menü öğesinin Intent kullanarak bir etkinliği başlatmasını istersiniz. Bu, uygulamanızdaki bir etkinlik veya başka bir uygulama olabilir. Kullanmak istediğiniz amacı biliyorsanız ve amacı başlatan belirli bir menü öğeniz varsa startActivity() ile uygun on-item-selected geri çağırma yöntemi (ör. onOptionsItemSelected() geri çağırması) sırasında amacı yürütebilirsiniz.

Ancak kullanıcının cihazında, amaç işleyen bir uygulama olduğundan emin değilseniz bunu çağıran bir menü öğesi eklemek, amacın bir etkinliğe çözümlenmemesi nedeniyle çalışmayan bir menü öğesiyle sonuçlanabilir. Android, bu sorunu çözmek için cihazda amacınızı işleyen etkinlikler bulduğunda menünüze dinamik olarak menü öğeleri eklemenize olanak tanır.

Bir amaç kabul eden kullanılabilir etkinliklere göre menü öğeleri eklemek için aşağıdakileri yapın:

  1. CATEGORY_ALTERNATIVE veya CATEGORY_SELECTED_ALTERNATIVE kategorisi ya da her ikisiyle birlikte diğer tüm koşulları kullanarak bir amaç tanımlayın.
  2. Menu.addIntentOptions() numaralı telefonu arayın. Android, amacı gerçekleştirebilecek uygulamaları arar ve bunları menünüze ekler.

Amaca uygun 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 amaca uygun bir amaç filtresi sağlayan her etkinlik için, amaç filtresinin android:label değerini menü öğesi başlığı, uygulama simgesini ise menü öğesi simgesi olarak kullanarak 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 dahil edilebilmesi için etkinliğinizin hizmetlerini diğer uygulamalara sunabilirsiniz. Bu durumda, daha önce açıklanan roller tersine döner.

Diğer uygulama menülerine dahil edilmek için intent filtresini her zamanki gibi tanımlayın ancak intent filtresi kategorisi için CATEGORY_ALTERNATIVE veya CATEGORY_SELECTED_ALTERNATIVE değerlerini ya da her ikisini de 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>

Niyet filtreleri yazma hakkında daha fazla bilgiyi Niyetler ve niyet filtreleri başlıklı makalede bulabilirsiniz.