एंड्रॉइड: बटन क्लिक पर विकल्प मेनू आइटम को सक्षम / अक्षम कैसे करें?


127

मैं इसे आसानी से कर सकता हूं जब मैं उपयोग कर रहा हूं onCreateOptionsMenuया onOptionsItemSelectedतरीके।

लेकिन मेरे पास स्क्रीन में कहीं एक बटन है, और उस बटन पर क्लिक करने पर, इसे संदर्भ मेनू आइटम को सक्षम / अक्षम करना चाहिए।

जवाबों:


272

वैसे भी, प्रलेखन में सभी चीजें शामिल हैं।

रनटाइम पर मेनू आइटम बदलना

एक बार गतिविधि बनने के बाद, onCreateOptionsMenu()विधि को केवल एक बार कहा जाता है, जैसा कि ऊपर वर्णित है। Menuजब तक आपकी गतिविधि नष्ट नहीं हो जाती, तब तक सिस्टम आपको इस पद्धति में परिभाषित करता है और फिर से उपयोग करता है। यदि आप पहली बार बनाए जाने के बाद किसी भी समय विकल्प मेनू बदलना चाहते हैं, तो आपको onPrepareOptionsMenu()विधि को ओवरराइड करना होगा । यह वर्तमान में मौजूद होने के कारण आपको मेनू ऑब्जेक्ट पास करता है। यदि आप अपने एप्लिकेशन की वर्तमान स्थिति के आधार पर मेनू आइटम हटाना, जोड़ना, अक्षम करना या सक्षम करना चाहते हैं तो यह उपयोगी है।

उदाहरण के लिए

@Override
public boolean onPrepareOptionsMenu (Menu menu) {
    if (isFinalized) {
        menu.getItem(1).setEnabled(false);
        // You can also use something like:
        // menu.findItem(R.id.example_foobar).setEnabled(false);
    }
    return true;
}

एंड्रॉइड 3.0 और उच्चतर पर, मेनू आइटम को एक्शन बार में प्रस्तुत किए जाने पर विकल्प मेनू को हमेशा खुला माना जाता है। जब कोई घटना होती है और आप मेनू अपडेट करना चाहते हैं, तो आपको invalidateOptionsMenu()सिस्टम कॉल का अनुरोध करने के लिए कॉल करना होगा onPrepareOptionsMenu()


2
setEnable()जब आप इस मेनू को दबाते हैं तो क्या होता है, लेकिन यह कैसे दिखता है (क्या गलत है, Android डेवलपर्स?) नहीं बदलता है। तो यह स्पष्ट है कि या तो अक्षम करें और शीर्षक बदलें, या अधिमानतः MenuItemअदृश्य बना दें।
व्लाद

19
त्वरित टिप: falseमेनू को पूरी तरह से अक्षम करने के लिए वापस लौटें ।
बार्ट फ्राइडरिच

5
इसके अलावा onPrepareOptionsMenu पर एपीआई टिप्पणी स्पष्ट रूप से बताती है: बेस क्लास कार्यान्वयन के माध्यम से डाइविंग क्लासेस को हमेशा (!) कॉल करना चाहिए। आप वहां अपना सुपर कॉल भूल गए।
AgentKnopf

दस्तावेज़ीकरण: developer.android.com/guide/topics/ui/…
जॉर्ज

रन-टाइम में जोड़े गए MenuItem के पूर्णांक आईडी को आप कैसे जानते हैं? आप उन्हें केवल नाम से जोड़ सकते हैं।
एंटोनियो सेस्टो

66

सभी एंड्रॉइड संस्करणों पर, सबसे आसान तरीका: इसे मेनू एक्शन आइकन को अक्षम के रूप में उपयोग करें और इसे अक्षम करें साथ ही अक्षम करें:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {

    MenuItem item = menu.findItem(R.id.menu_my_item);

    if (myItemShouldBeEnabled) {
        item.setEnabled(true);
        item.getIcon().setAlpha(255);
    } else {
        // disabled
        item.setEnabled(false);
        item.getIcon().setAlpha(130);
    }
}

1
जब आप दृश्यता को असत्य पर सेट कर सकते हैं तो अल्फा 0 से सेट क्यों करें?
MLProgrammer-CiM

8
मैं अल्फा को 0 पर नहीं, बल्कि 130 पर सेट कर रहा हूं।
फ्रैंक

8
बटन के संदर्भ पर निर्भर करता है। यदि सुविधा बटन सामान्य रूप से काम करेगा, तो वर्तमान स्थिति में पूरी तरह से अनुपयोगी है, तो हाँ दृश्यता अदृश्य / चली जानी चाहिए। हालाँकि, यदि बटन सामान्य रूप से काम करेगा तो COULD को उपयोग करने योग्य माना जाएगा, जो भी कारण हो (जैसे। यदि उपयोगकर्ता एक प्रीमियम सदस्य बन जाता है, यदि उपयोगकर्ता साइन इन करता है, यदि उपयोगकर्ता इंटरनेट से जुड़ता है, आदि) तो यह समझ में आना अच्छा है। क्योंकि तब यह उपयोगकर्ता को पता चलता है कि कुछ मौजूदा सुविधा है, जिनके पास किसी कारण से पहुंच नहीं है।
19

6
अदृश्य को आइकन सेट करना लगभग सभी उपयोग के मामलों में बेहतर नहीं है। यदि आपके पास एक समूह है तो बेहतर है कि वे अपने पदों पर बने रहें और बाहर निकलने पर उपयोगकर्ता को इंगित करता है कि एक विकल्प है जिसे एक निश्चित कार्यक्रम स्थिति में सक्षम किया जा सकता है। अदृश्य और अदृश्य चीज़ बनाना और शायद लेआउट में बदलाव करना बहुत मूर्खतापूर्ण है। एक कारण यह है कि अधिकांश मेनू ग्रे आउट आइटम हैं और उन्हें मोड के आधार पर हटाया नहीं गया है।
रिचीह

1
अगर मेनू में आइकन नहीं है तो कैसे होगा? आप सेट्ल्हा () सेट नहीं कर सकते।
लतीफ़ अनवर

42

आप विकल्प मेनू बनाते समय आइटम को एक चर के रूप में सहेज सकते हैं और फिर इसके गुणों को अपनी इच्छानुसार बदल सकते हैं।

private MenuItem securedConnection;
private MenuItem insecuredConnection;

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.connect_menu, menu);
    securedConnection = menu.getItem(0);
    insecuredConnection =  menu.getItem(1);
    return true;
}

public void foo(){
       securedConnection.setEnabled(true);
}    

यह किसी भी Android संस्करण के लिए सही प्रतिक्रिया है। मान्य प्रतिक्रिया केवल API 11> उपकरणों के लिए मान्य है।
मार्को HC

2
मैंने यह कोशिश की है, और यह काम नहीं करता है। क्या आपका मतलब था onPrepareOptionsMenu?
क्रिस्टोफर पिक्सले


5

जब AsyncTask किया जाता है तो आइटम को सक्षम या अक्षम करने के लिए वर्तमान मेनू को कैसे अपडेट किया जाए।

मेरे उपयोग के मामले में, मुझे अपने मेनू को अक्षम करने की आवश्यकता थी, जबकि मेरा AsyncTask डेटा लोड कर रहा था, फिर सभी डेटा लोड करने के बाद, उपयोगकर्ता को इसका उपयोग करने देने के लिए मुझे सभी मेनू को फिर से सक्षम करने की आवश्यकता थी।

डेटा को लोड करने के दौरान उपयोगकर्ताओं को मेनू आइटम पर क्लिक करने देने के लिए इस ऐप को रोकता है।

सबसे पहले, मैं एक राज्य चर घोषित करता हूं, यदि चर 0 है तो मेनू दिखाया गया है, यदि वह चर 1 है तो मेनू छिपा हुआ है।

private mMenuState = 1; //I initialize it on 1 since I need all elements to be hidden when my activity starts loading.

फिर मेरे onCreateOptionsMenu()चर में मैं इस चर की जांच करता हूं, यदि यह 1 है तो मैं अपने सभी आइटमों को अक्षम कर देता हूं, यदि नहीं, तो मैं सिर्फ उन सभी को दिखाता हूं

 @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.menu_galeria_pictos, menu);

        if(mMenuState==1){
            for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(false);
            }
        }else{
             for (int i = 0; i < menu.size(); i++) {
                menu.getItem(i).setVisible(true);
            }
        }

        return super.onCreateOptionsMenu(menu);
    }

अब, जब मेरी गतिविधि शुरू होती है, तो मुझे onCreateOptionsMenu()केवल एक बार बुलाया जाएगा, और मेरे सभी आइटम चले जाएंगे क्योंकि मैंने शुरुआत में उनके लिए राज्य स्थापित किया था।

फिर मैं एक AsyncTask बनाता हूं जहां मैंने उस स्टेट वेरिएबल को 0 में सेट किया है onPostExecute()

यह चरण बहुत महत्वपूर्ण है!

जब आप कॉल invalidateOptionsMenu();करेंगे तो यह रिलॉन्च होगाonCreateOptionsMenu();

इसलिए, अपने राज्य को 0 पर सेट करने के बाद, मैं सिर्फ सभी मेनू को फिर से तैयार करता हूं, लेकिन इस बार 0 पर मेरे चर के साथ, उस ने कहा, सभी मेनू को सभी अतुल्यकालिक प्रक्रिया के पूरा होने के बाद दिखाया जाएगा, और फिर मेरा उपयोगकर्ता मेनू का उपयोग कर सकता है ।

 public class LoadMyGroups extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            mMenuState = 1; //you can set here the state of the menu too if you dont want to initialize it at global declaration. 

        }

        @Override
        protected Void doInBackground(Void... voids) {
           //Background work

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            mMenuState=0; //We change the state and relaunch onCreateOptionsMenu
            invalidateOptionsMenu(); //Relaunch onCreateOptionsMenu

        }
    }

परिणाम

यहाँ छवि विवरण दर्ज करें


2

जब आप नेविगेशन दराज पर प्रदर्शन करते हैं तो सबसे अच्छा समाधान

@Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        menu.setGroupVisible(0,false);
        return true;
    }

यह पूरे मेनू को छुपाता है और इसे फिर से खोलना असंभव बना देता है
MrStahlfelge

2

एक पुराने प्रश्न के लिए अधिक आधुनिक उत्तर:

MainActivity.kt

private var myMenuIconEnabled by Delegates.observable(true) { _, old, new ->
    if (new != old) invalidateOptionsMenu()
}

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

    findViewById<Button>(R.id.my_button).setOnClickListener { myMenuIconEnabled = false }
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
    menuInflater.inflate(R.menu.menu_main_activity, menu)
    return super.onCreateOptionsMenu(menu)
}

override fun onPrepareOptionsMenu(menu: Menu): Boolean {
    menu.findItem(R.id.action_my_action).isEnabled = myMenuIconEnabled
    return super.onPrepareOptionsMenu(menu)
}

menu_main_activity.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
    android:id="@+id/action_my_action"
    android:icon="@drawable/ic_my_icon_24dp"
    app:iconTint="@drawable/menu_item_icon_selector"
    android:title="My title"
    app:showAsAction="always" />
</menu>

menu_item_icon_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?enabledMenuIconColor" android:state_enabled="true" />
<item android:color="?disabledMenuIconColor" />

attrs.xml

<resources>   
    <attr name="enabledMenuIconColor" format="reference|color"/>
    <attr name="disabledMenuIconColor" format="reference|color"/>
</resources>

styles.xml or themes.xml

<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="disabledMenuIconColor">@color/white_30_alpha</item>
    <item name="enabledMenuIconColor">@android:color/white</item>

महान दृष्टिकोण जो ऐप के चारों ओर बहुत बॉयलरप्लेट के बिना उपयोग किया जा सकता है।
आर्थर

आपकी क्या समस्या हैं?
ExpensiveBelly

@ExpensiveBelly प्रति समस्या नहीं है, बस सार्वजनिक सूचना है।
बिग मैक्लेरजैग

1
  @Override
        public boolean onOptionsItemSelected(MenuItem item) {

            switch (item.getItemId()) {

                case R.id.item_id:

                       //Your Code....

                        item.setEnabled(false);
                        break;
              }
            return super.onOptionsItemSelected(item);
     }

समीक्षा से: हाय, कृपया स्रोत कोड के साथ जवाब न दें। आपका समाधान कैसे काम करता है, इसके बारे में अच्छा विवरण देने का प्रयास करें। देखें: मैं एक अच्छा जवाब कैसे लिखूं? । धन्यवाद
sɐunıɔ ןɐ qɐp

1

मैंने जो किया वह मेनू के संदर्भ को सहेजता था onCreateOptionsMenu। यह प्रत्येक व्यक्तिगत आइटम को बचाने के बजाय नीर के उत्तर के समान है, मैंने पूरे मेनू को बचा लिया।

मेनू की घोषणा करें Menu toolbarMenu;

फिर onCreateOptionsMenuमेनू को अपने वेरिएबल में सेव करें

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

अब आप अपने मेनू और इसके सभी सामानों को कभी भी उपयोग कर सकते हैं। toolbarMenu.getItem(0).setEnabled(false);


0
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    // getMenuInflater().inflate(R.menu.home, menu);
    return false;
}

2
हालांकि यह कोड ओपी के प्रश्न का उत्तर दे सकता है, लेकिन स्पष्टीकरण के कुछ शब्द वर्तमान और भविष्य के उपयोगकर्ताओं को आपकी प्रतिक्रिया को और भी बेहतर ढंग से समझने में मदद करेंगे।
Thom

0

यदि दृश्य मेनू

menu.findItem(R.id.id_name).setVisible(true);

यदि मेनू को छिपाएं

menu.findItem(R.id.id_name).setVisible(false);

-4

आम तौर पर रनटाइम में आपके विचारों के गुणों को बदल सकते हैं:

(Button) item = (Button) findViewById(R.id.idBut);

और फिर...

item.setVisibility(false)

परंतु

यदि आप ContextMenu से विकल्पों की डी दृश्यता को संशोधित करना चाहते हैं, तो अपने बटन को दबाएं, आप एक ध्वज को सक्रिय कर सकते हैं, और फिर OnCreateContextMenu में आप ऐसा कुछ कर सकते हैं:

 @Override
        public void onCreateContextMenu(ContextMenu menu, 
                View v,ContextMenu.ContextMenuInfo menuInfo) {

            super.onCreateContextMenu(menu, v, menuInfo);

                menu.setHeaderTitle(R.string.context_title);

                if (flagIsOn()) {
                    addMenuItem(menu, "Option available", true);
                } else {
                    Toast.makeText(this, "Option not available", 500).show();
                }

        }

आशा है कि ये आपकी मदद करेगा


मुझे कहना होगा कि आप गलत हो रहे हैं, मैं चाहता हूं कि मेनू आइटम अक्षम हो, बटन नहीं।
विकास

मेरा जवाब पूरा हो गया है। यह कोड यह काम करता है, मैंने अपनी परियोजनाओं में इस्तेमाल किया है
एरिक

1
अच्छी तरह से काम के लिए धन्यवाद, लेकिन आपको ठीक से प्रश्न पढ़ना चाहिए जो मैंने पहले ही कहा है कि मैं इसे onCreateContextMenuविधि में बदल सकता हूं । लेकिन मैं इस विधि से संदर्भ मेनू को बाहर की ओर एक्सेस करना चाहता हूं।
विकास

onCreateContextMenuकेवल एक बार कॉल किया जाएगा, लेकिन मैं मेनू आइटम को सक्षम / अक्षम करने के लिए बहुत समय बटन पर क्लिक कर सकता हूं।
विकास

हां, लेकिन संदर्भ मेनू को सामान्य रूप से छिपा हुआ किया जाता है। यदि आप अपना 'कहीं का बटन' दबाते हैं और जैसा कि मैंने कहा झंडा सेट किया है, तो यह संदर्भ मेनू दिखाई नहीं देता है और अगली बार जब आप अपना संदर्भ मेनू पुनः लोड करते हैं, तो यह विकल्प अदृश्य होगा। एक अन्य विकल्प अन्य तरीकों के साथ घटनाओं को संभालने के लिए एक ही उपस्थिति के साथ एक और प्रकार का मेनू करना है।
एरिक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.