ActionBar'da gösterilen bir menü öğesi nasıl güncellenir?


94

2 parçadan oluşan bir Aktivitem var. Her ikisi de ListFragments'tır ve her ikisi de MenuItems'i Menu'ye ekler. Android: showAsAction özniteliğini ActionBar'da bir düğme olarak göstermesi için ayarladığım bir MenuItem'im var. Hangi iyi çalışıyor.

Şimdi MenuItem duruma bağlıdır. Bir kuyruğu duraklatmak ve devam ettirmek için bir Duraklat / Sürdür menü seçeneğidir. Benim sorunum, Parça oluşturulduğunda onun ilk heykelini nasıl yerleştireceğimi çözemiyorum.

Durumu, kuyruğun duraklatılıp duraklatılmamasına bağlıdır. Bu yüzden kuyruğu alan ve kuyruğun durumuna bağlı olarak boole (duraklatılmış) ayarlayan bir AsyncTask'ım var. Kuyruğun bilinen son durumuna göre Duraklat menü öğesi metnini ayarlamak için onPrepareOptionsMenu'yu arıyorum ve MenuItem'i gerçek menüde bırakırsam bu harika çalışıyor. Menü simgesine dokunduğunuzda PrePrepareOptionsMenu çalıştırılır ve görüntülenmeden önce menü güncellenir.

Sorun şu ki, aynı MenuItem'i ActionBar'a (showAsAction) koyarsam, onPrepareOptionsMenu'yu çağırmak zorunda kalmadan onu nasıl güncellemeye zorlayabilirim? Bunu yapabilmem gerekiyor çünkü uygulamanın ilk açılışında kuyruğu almak için bir istek gönderiyorum, ancak ActionBar kurulup görüntülendikten sonra görev geri dönüyor. Parçamda her sıra güncellemesi aldığımda çağrılan bir işleyici oluşturdum, ancak buradan, ActionBar'daki MenuItem metnimin metnini nasıl güncelleyebilirim? OnPrepareOptionMenu dışında şu anda ayarlanmış olan Menüyü değiştirecek bir yol bulamıyorum.

Rob W.

Yanıtlar:


175

Seçenek 1: Deneyin invalidateOptionsMenu(). Bunun eylem çubuğunu hemen yeniden çizmeye zorlayıp zorlamayacağını bilmiyorum.

Seçenek # 2: getActionView()Etkilenen kişi için herhangi bir şey döndürüp döndürmediğine bakın MenuItem. showAsActionSizin için basitçe otomatik olarak eylem görünümleri oluşturması mümkündür . Öyleyse, muhtemelen bunu etkinleştirebilir / devre dışı bırakabilirsiniz View.

OnPrepareOptionMenu dışında şu anda ayarlanmış olan Menüyü değiştirecek bir yol bulamıyorum.

Teslim edildiğin Menunesneye asılabilirsin onCreateOptionsMenu(). Dokümanlardan alıntı yapmak :

OnCreateOptionsMenu () bir dahaki sefere çağrılana kadar, menüye (ve onCreateOptionsMenu ()) çağrılana kadar, menüye (ve bundan oluşturulan herhangi bir öğeye) güvenle basılı tutabilir ve istediğiniz şekilde değişiklik yapabilirsiniz.


2
Seçenek 1'i denedim ve bu hile yaptı. UI'yi ayrı bir iş parçacığından geri aramada güncellemeye çalıştığım için, aslında UI iş parçacığında olmadığım için bir istisna atıyordu. Bunu düzeltmek için, bir İşleyici oluşturdum ve geri aramam çağrıldığında işleyiciye bir yenileme mesajı gönderdim. Ama nihayetinde menüyü yenilemek için getActivity () .validateOptionsMenu () kullandım.
brockoli

@brockoli: Ah, güzel! Bu yöntem için Javadocs'un ifadeleri göz önüne alındığında, istenen etkiye sahip olacağından şüpheliydim, ancak ilk etapta API Seviye 11'e eklemelerinin nedeni bu gibi görünüyordu. İşe yaradığını duyduğuma sevindim!
CommonsWare

Bunu anlamaya çalışırken kafamı duvara vuruyorum ve bu bir cazibe gibi çalışıyor!
MinceMan

7
Destek kitaplığını kullanıyorsanız supportInvalidateOptionsMenu()bunun yerine kullanın
Tim Kist

2
@TimKist, supportInvalidateOptionsMenu()artık kullanımdan kaldırıldı; güvenle kullanabilirsiniz invalidateOptionsMenu().
Primož Kralj

12

benim durumumda: invalidateOptionsMenumetni orijinaline yeniden ayarladım, ancak doğrudan menü öğesine erişerek ve istenen metni yeniden yazmak sorunsuz çalıştı:

if (mnuTopMenuActionBar_ != null) {
    MenuItem mnuPageIndex = mnuTopMenuActionBar_
        .findItem(R.id.menu_magazin_pageOfPage_text);

    if (mnuPageIndex != null) {
        if (getScreenOrientation() == 1) {
            mnuPageIndex.setTitle((i + 1) + " von " + pages);
        }
        else {
            mnuPageIndex.setTitle(
                (i + 1) + " + " + (i + 2) + " " + " von " + pages);
        }
        // invalidateOptionsMenu();
    }
}

Aşağıdaki yorumdan dolayı aşağıdaki kod aracılığıyla menü öğesine erişebildim:

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

İle ActionBar görünümünü nasıl elde ettiniz mnuTopMenuActionBar_?
Paul Mennega

1
eylem çubuğu başlatıldığında, görünümü bir üye değişkenine kaydettim ... şöyle: @Override public boolean onCreateOptionsMenu (Menu menu) {MenuInflater inflater = getMenuInflater (); inflater.inflate (R.menu.magazine_swipe_activity, menü); mnuTopMenuActionBar_ = menü; doğruya dön; }
cV2

Bunu yaparak senkronizasyon sorunları yaşayabilirsiniz, değil mi? Demek istediğim. onCreateOptionMenu'nun tam olarak ne zaman çalışacağını bilmiyorsunuz, bu nedenle kod parçanıza ilklendirilmemiş ile ulaşabilirsiniz mnuTopMenuActionBar_, değil mi? Bunun etrafında nasıl çalışırsın?
acrespo

hey, eylem çubuğu kullanılırsa (evet, işte burada) bu yöntem her zaman çağrılır, bu nedenle bunda bir sorun yok ... (doğrudan etkinlik başlangıcında) stackoverflow.com/questions/7705927/…
cV2

11

Fragment'tan menüyü yenilemek için şunu aramanız yeterlidir:

getActivity().invalidateOptionsMenu();

4

Bu kodu kullandım:

public boolean onPrepareOptionsMenu (Menu menu) {       
    MenuInflater inflater = getMenuInflater();
    TextView title  = (TextView) findViewById(R.id.title);
    menu.getItem(0).setTitle(
        getString(R.string.payFor) + " " + title.getText().toString());
    menu.getItem(1).setTitle(getString(R.string.payFor) + "...");
    return true;        
}

Ve benim için bir cazibe gibi çalıştı OnPrepareOptionsMenu burada bulabilirsiniz


4
Buradaki MenuInflater'ın amacı nedir?
IgorGanapolsky

Bu harika
Steve Kamau

2

İlk olarak, oncreateOptionMenu () 'da bir koşul ayarlamanızdan önce işlem çubuğu öğelerini güncellemek için lütfen iki kod satırını izleyin. Örneğin:

Boolean mISQuizItemSelected = false;

/**
 * Called to inflate the action bar menus
 *
 * @param menu
 *      the menu
 *
 * @return true, if successful
 */

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu items for use in the action bar

    inflater.inflate(R.menu.menu_demo, menu);

    //condition to hide the menus
    if (mISQuizItemSelected) {
        for (int i = 0; i < menu.size(); i++) {
            menu.getItem(i).setVisible(false);
        }
    }

    return super.onCreateOptionsMenu(menu);
}

/**
 * Called when the item on the action bar being selected.
 *
 * @param item
 *      menuitem being selected
 *
 * @return true if the menuitem id being selected is matched
 * false if none of the menuitems id are matched
 */
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (item.getId() == R.id.action_quiz) {
        //to navigate based on the usertype either learner or leo
        mISQuizItemSelected = true;

        ActionBar actionBar = getActionBar();
        invalidateOptionMenu();
    }
}

1

Açıklık getirmek için, bir kaynağı ele geçirmenin doğrudan bir örneğinin aşağıdakilerden gösterilebileceğini düşündüm ki, bu sorunun cevabına hızlı bir doğrudan örnekle katkıda bulunduğunu düşünüyorum.

private MenuItem menuItem_;

@Override
public boolean onCreateOptionsMenu(Menu menuF) 
{
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.menu_layout, menuF);
    menuItem_ = menuF.findItem(R.id.menu_item_identifier);
    return true;
}

Bu durumda, başlangıçta bir MenuItem referansını tutarsınız ve daha sonra belirli bir zamanda durumunu değiştirirsiniz (örneğin simge durumu değişiklikleri için).


-1

In KOTLIN 1.2 basitçe çağırır:

invalidateOptionsMenu()

ve onCreateOptionsMenuişlev yeniden çağrılacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.