ActionBar में दिखाए गए मेनू आइटम को कैसे अपडेट करें?


93

मेरे पास एक गतिविधि है जिसमें 2 टुकड़े हैं। दोनों ListFragments हैं और दोनों मेनू में MenuItems का योगदान करते हैं। मेरे पास एक MenuItem है जिसे मैंने विशेषता android: showAsAction में सेट किया है, ताकि यह एक्शनबार पर एक बटन के रूप में दिखाई दे। जो ठीक काम करता है।

अब MenuItem राज्य निर्भर है। यह एक कतार को रोकने और फिर से शुरू करने के लिए एक पॉज़ / रिज्यूमे मेनू विकल्प है। मेरी समस्या यह है कि मैं यह पता नहीं लगा सकता कि फ्रेगमेंट बनने पर यह प्रारंभिक प्रतिमा कैसे सेट करें।

यह इस बात पर निर्भर करता है कि कतार रुकी है या नहीं। इसलिए मेरे पास एक AsyncTask है जो कतार को प्राप्त करता है और कतार की स्थिति के आधार पर एक बूलियन (रुका हुआ) सेट करता है। मैं कतार के अंतिम ज्ञात स्थिति के आधार पर रोकें मेनू आइटम के लिए पाठ सेट करने के लिए onPrepareOptionsMenu पर कॉल कर रहा हूं और अगर मैं वास्तविक मेनू में MenuItem को छोड़ता हूं तो यह बहुत अच्छा काम करता है। आप मेनू आइकन पर टैप करें और onPrepareOptionsMenu को निकाल दिया गया है और प्रदर्शित होने से पहले मेनू को अपडेट किया गया है।

समस्या यह है, अगर मैं ActionBar (showAsAction) पर वही MenuItem डाल देता हूं, तो मैं इसे onPrepareOptionsMenu पर कॉल किए बिना अपडेट करने के लिए कैसे मजबूर कर सकता हूं? मुझे ऐसा करने में सक्षम होने की आवश्यकता है क्योंकि ऐप के पहले लॉन्च पर, मैं कतार प्राप्त करने के लिए एक अनुरोध भेजता हूं, लेकिन ActionBar सेटअप होने और प्रदर्शित होने के बाद कार्य वापस आ जाता है। मैंने अपने टुकड़े में एक हैंडलर बनाया है जिसे हर बार जब मुझे कतार का अद्यतन प्राप्त होता है, तो मुझे कॉल किया जाता है, लेकिन वहां से, मैं एक्शनबेर पर अपने मेनू इटेम के लिए पाठ कैसे अपडेट कर सकता हूं? मैं वर्तमान में सेट मेनू को चालू करने के लिए एक तरीका खोजने के लिए प्रतीत नहीं कर सकता इसे onPrepareOptionMenu को छोड़कर।

रोब डब्ल्यू।

जवाबों:


174

विकल्प # 1: प्रयास करें invalidateOptionsMenu()। मुझे नहीं पता कि यह एक्शन बार के तत्काल सुधार को बाध्य करेगा या नहीं।

विकल्प # 2: देखें कि क्या getActionView()प्रभावितों के लिए कुछ भी लौटाता है MenuItem। यह संभव है कि showAsActionबस स्वचालित रूप से आपके लिए कार्रवाई के विचार बनाता है। यदि ऐसा है, तो आप संभवतः इसे अक्षम / अक्षम कर सकते हैं View

मैं वर्तमान में सेट मेनू को चालू करने के लिए एक तरीका खोजने के लिए प्रतीत नहीं कर सकता इसे onPrepareOptionMenu को छोड़कर।

आप उस Menuवस्तु पर लटका सकते हैं जिसे आप सौंपे गए थे onCreateOptionsMenu()डॉक्स का हवाला देते हुए :

जब तक अगली बार onCreateOptionsMenu () कहा जाता है, तब तक आप इसे सुरक्षित रूप से मेनू पर रख सकते हैं (और इससे बनी कोई भी वस्तु), इसे वांछित रूप से संशोधित कर सकते हैं।


2
# 1 विकल्प की कोशिश की और यह चाल चली। चूंकि मैं एक अलग थ्रेड से कॉलबैक में UI को अपडेट करने की कोशिश कर रहा था, इसलिए यह एक अपवाद फेंक रहा था क्योंकि मैं वास्तव में यूआई थ्रेड पर नहीं था। इसे ठीक करने के लिए, मैंने एक हैंडलर बनाया और हैंडलर को एक ताज़ा संदेश भेजा जब मेरा कॉलबैक कहा गया। लेकिन अंततः मैंने मेन्यू को रिफ्रेश करने के लिए getActivity ()। अमान्यateOptionsMenu () का उपयोग किया।
ब्रोकली

@ ब्रोकली: आह, अच्छा! उस पद्धति के लिए Javadocs के वाक्यांशों को देखते हुए, मुझे संदेह था कि इसका वांछित प्रभाव होगा, हालांकि ऐसा लगेगा कि यही कारण है कि उन्होंने इसे एपीआई स्तर 11 में पहले स्थान पर जोड़ा था। खुशी है कि यह आपके लिए काम कर रहा है!
कॉमन्सवेयर

मैं दीवार के खिलाफ अपना सिर मार रहा हूं, यह पता लगाने की कोशिश कर रहा हूं और यह एक आकर्षण की तरह काम करता है!
मिन्समैन

7
यदि आप समर्थन पुस्तकालय का उपयोग कर रहे हैं, तो supportInvalidateOptionsMenu()इसके बजाय का उपयोग करें
टिम किस्ट

2
@ तीमिस्ट, supportInvalidateOptionsMenu()अब पदावनत हो गया है; आप सुरक्षित रूप से उपयोग कर सकते हैं invalidateOptionsMenu()
प्रिमो क्रालज

12

मेरे मामले में: invalidateOptionsMenuमूल पाठ को बस फिर से व्यवस्थित किया, लेकिन सीधे मेनू आइटम तक पहुंच और इच्छा पाठ को फिर से लिखना समस्याओं के साथ काम किया:

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();
    }
}

नीचे टिप्पणी के कारण, मैं निम्नलिखित कोड के माध्यम से मेनू आइटम का उपयोग करने में सक्षम था:

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

आपको ActionBar व्यू के साथ एक हैंडल कैसे मिला mnuTopMenuActionBar_?
पॉल मेन्नेगा

1
जब एक्शन बार आरंभीकृत हो जाता है, तो मैंने एक सदस्य चर को दृश्य सहेज लिया ... इस तरह: @Override सार्वजनिक बूलियन onCreateOptionsMenu (मेनू मेनू) {MenuInflater inflater = getMenuInflater (); inflater.inflate (R.menu.magazine_swipe_activity, menu); mnuTopMenuActionBar_ = मेनू; सच लौटना; }
cV2

ऐसा करने से, आप सिंक्रनाइज़ेशन समस्याएँ ठीक कर सकते हैं? मेरा मतलब। तुम नहीं जानते कि वास्तव में जब onCreateOptionMenu चलने वाला है, तो आप अपने कोड को mnuTopMenuActionBar_अनइंस्टाल्यूटेड, राइट के साथ पहुंचा सकते हैं ? आप उसके आसपास कैसे काम करेंगे?
एक्रीसो

अरे, अगर एक्शनबार का उपयोग किया जाता है (हाँ, यहाँ यह है) इस पद्धति को हमेशा कहा जाता है, इसलिए इसके साथ कोई समस्या नहीं है ... (सीधे गतिविधि शुरू होने पर) stackoverflow.com/questions/7705927/…
cV2

11

Fragment से मेनू को ताज़ा करने के लिए बस कॉल करें:

getActivity().invalidateOptionsMenu();

4

मैंने इस कोड का उपयोग किया है:

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;        
}

और मेरे लिए एक आकर्षण की तरह काम किया है आप यहाँ OnPrepareOptionsMenu पा सकते हैं


4
MenuInflater का उद्देश्य यहाँ क्या है?
इगोरगानापोलस्की

यह शानदार है
स्टीव कामौ

2

पहले कार्रवाई बार आइटम को अपडेट करने के लिए कोड की दो पंक्तियों का पालन करें, इससे पहले कि आप oncreateOptionMenu () में एक शर्त सेट करें। उदाहरण के लिए:

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

स्पष्टता के लिए, मैंने सोचा कि संसाधन पर हथियाने का एक प्रत्यक्ष उदाहरण निम्नलिखित से दिखाया जा सकता है जो मुझे लगता है कि इस प्रश्न के लिए त्वरित प्रत्यक्ष उदाहरण के साथ प्रतिक्रिया में योगदान देता है।

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;
}

इस मामले में आप शुरुआत में एक MenuItem संदर्भ को पकड़ते हैं और फिर बाद में दिए गए बिंदु पर उस समय की स्थिति (उदाहरण के लिए आइकन स्थिति में परिवर्तन) को बदलते हैं।


-1

में Kotlin 1.2 बस फोन:

invalidateOptionsMenu()

और onCreateOptionsMenuफ़ंक्शन को फिर से बुलाया जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.