Android में मेनू आइटम टेक्स्ट को गतिशील रूप से कैसे बदलें


212

मैं onOptionsItemSelected(MenuItem item)विधि के बाहर से एक मेनू आइटम का शीर्षक बदलने की कोशिश कर रहा हूं ।

मैं पहले से ही निम्न कार्य करता हूं;

public boolean onOptionsItemSelected(MenuItem item) {
  try {
    switch(item.getItemId()) {
      case R.id.bedSwitch:
        if(item.getTitle().equals("Set to 'In bed'")) {
          item.setTitle("Set to 'Out of bed'");
          inBed = false;
        } else {
          item.setTitle("Set to 'In bed'");
          inBed = true;
        }
        break;
    }
  } catch(Exception e) {
    Log.i("Sleep Recorder", e.toString());
  }
  return true;
}

हालाँकि मैं इस विधि के बाहर किसी विशेष मेनू आइटम के शीर्षक को संशोधित करने में सक्षम होना चाहता हूँ।


stackoverflow.com/a/32072318/1651286 का स्वीकृत उत्तर होना चाहिए
अखिल पिता

जवाबों:


127

जैसा कि JxDarkAngel ने सुझाव दिया है, इसे अपनी गतिविधि में कहीं से भी कॉल करना ,

invalidateOptionsMenu();

और फिर ओवरराइडिंग:

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
  MenuItem item = menu.findItem(R.id.bedSwitch);
    if (item.getTitle().equals("Set to 'In bed'")) {
        item.setTitle("Set to 'Out of bed'");
        inBed = false;
    } else {
        item.setTitle("Set to 'In bed'");
        inBed = true;
    }
  return super.onPrepareOptionsMenu(menu);
}

ज्यादा बेहतर विकल्प है। मैंने https://stackoverflow.com/a/17496503/568197 से उत्तर का उपयोग किया


सबसे अच्छा उपाय। क्योंकि यह एक पहिया को सुदृढ़ करने के बजाय एंड्रॉइड विधि को ओवरराइड करता है।
अजलान जमाल

बस ध्यान दें कि onPrepareOptionsMenu()एंड्रॉइड फ्रेमवर्क द्वारा अक्सर कहा जाता है, उदाहरण के लिए जब कोई गतिविधि प्रदर्शित होती है और हर बार मेनू प्रदर्शित होता है। तो यह बहुत कुशल नहीं हो सकता है, अगर आपका मेनू बहुत बार नहीं बदलता है।
श्री-आईडीई

1
invalidateOptionsMenu()भी कॉल करेगा onCreateOptionsMenu(), इसलिए आप अपडेट लॉजिक को इसमें डाल सकते हैं onCreateOptionsMenu()
मिस्टर-आईडीई

यदि आप इसे इस प्रश्न के लिए प्रासंगिक
मानते हैं

@Garbit ने मूल प्रश्न से अपने कोड का उपयोग करने के लिए अपडेट किया!
टॉड देलांद

375

मैं आपको onCreateOptionsMenu में प्राप्त होने वाली मेनू ऑब्जेक्ट के लिए गतिविधि के भीतर एक संदर्भ रखने का सुझाव दूंगा और फिर MenuItem को पुनः प्राप्त करने के लिए इसका उपयोग करके जिसमें परिवर्तन की आवश्यकता होती है। उदाहरण के लिए, आप निम्नलिखित की तर्ज पर कुछ कर सकते हैं:

public class YourActivity extends Activity {

  private Menu menu;
  private String inBedMenuTitle = "Set to 'In bed'";
  private String outOfBedMenuTitle = "Set to 'Out of bed'";
  private boolean inBed = false;

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

    // Create your menu...

    this.menu = menu;
    return true;
  }

  private void updateMenuTitles() {
    MenuItem bedMenuItem = menu.findItem(R.id.bedSwitch);
    if (inBed) {
      bedMenuItem.setTitle(outOfBedMenuTitle);
    } else {
      bedMenuItem.setTitle(inBedMenuTitle);
    }
  }

}

वैकल्पिक रूप से, आप मेनू प्रदर्शित होने पर हर बार मेनू आइटम को अपडेट करने के लिए onPrepareOptionsMenu को ओवरराइड कर सकते हैं ।


1
मैं हमेशा उम्मीद करता हूं कि एंड्रॉइड इस तरह की समस्याओं का अधिक सुरुचिपूर्ण समाधान करेगा। लगता है सबसे सरल जवाब अक्सर सबसे अच्छा होता है - धन्यवाद।
स्टीवन वोल्फ

12

आप इसे एक वैश्विक "मेनू" ऑब्जेक्ट बना सकते हैं फिर इसे onCreateOptionMenu में असाइन करें

public class ExampleActivity extends AppCompatActivity
    Menu menu;

फिर यहाँ असाइन करें

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

फिर बाद में आवश्यक वस्तुओं को प्राप्त करने के लिए असाइन किए गए मेनू ऑब्जेक्ट का उपयोग करें

menu.findItem(R.id.bedSwitch).setTitle("Your Text");

5

एक setOptionsTitle () विधि बनाएं और अपनी कक्षा में एक फ़ील्ड सेट करें। जैसे कि:

String bedStatus = "Set to 'Out of Bed'";

...

public void setOptionsTitle(String status)
{
    bedStatus = status;

}

अब जब मेनू पॉपुलेट हो जाता है, तो शीर्षक को अपनी स्थिति के अनुसार बदल दें:

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

        menu.add(bedStatus);


        // Return true so that the menu gets displayed.
        return true;
    }

गतिविधि के प्रस्तुत होने के बाद मुझे इसे सेट करने में सक्षम होना चाहिए। इसलिए इसलिए उन दो तरीकों के अंदर नहीं
Gbit

आपकी गतिविधि के बाद किसी भी बिंदु पर कॉल सेट करें। मुझे लगता है कि मैं समझ नहीं पा रहा हूं कि आपकी इच्छा क्या है क्योंकि "मुझे गतिविधि के बाद इसे सेट करने में सक्षम होने की आवश्यकता है" का अर्थ है मेरे द्वारा सेटकॉन्टेंट (R.layout.id) कॉल करने के बाद, आपको विकल्प बदलने की आवश्यकता हो सकती है मेनू प्रदर्शित करता है (जो आप setOptionsTitle के साथ कर सकते हैं) () - किसी भी विधि से, कहीं भी, कभी भी।
जैक

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

3

आप बेहतर ओवरराइड onPrepareOptionsMenu का उपयोग करते हैं

menu.Clear ();
   if (TabActual == TabSelec.Anuncio)
   {
       menu.Add(10, 11, 0, "Crear anuncio");
       menu.Add(10, 12, 1, "Modificar anuncio");
       menu.Add(10, 13, 2, "Eliminar anuncio");
       menu.Add(10, 14, 3, "Actualizar");
   }
   if (TabActual == TabSelec.Fotos)
   {
       menu.Add(20, 21, 0, "Subir foto");
       menu.Add(20, 22, 1, "Actualizar");
   }
   if (TabActual == TabSelec.Comentarios)
   {
       menu.Add(30, 31, 0, "Actualizar");
   }

यहाँ एक उदाहरण है


वास्तव में, इच्छित दृष्टिकोण का उपयोग करें। :) यदि आप मेनू के एक स्थानीय संदर्भ को रखने का निर्णय लेते हैं, तो आपको संदर्भ लीक के बारे में चिंता करने की आवश्यकता होगी जो मुझे लगता है। या शायद नहीं। लेकिन निश्चित रूप से इस दृष्टिकोण के साथ नहीं।
विलियम टी। मल्लार्ड २

3

मैं इस कोड का उपयोग अपने निचले नेविगेशन आइटम को कॉस्ट्यूम करने के लिए करता हूं

BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");

2

अपने मेनू क्षेत्र की घोषणा करें।

private Menu menu;

निम्नलिखित onCreateOptionsMenu () विधि है

public boolean onCreateOptionsMenu(Menu menu) {
this.menu = menu;
    try {
        getMenuInflater().inflate(R.menu.menu_main,menu);
    } catch (Exception e) {
        e.printStackTrace();
        Log.i(TAG, "onCreateOptionsMenu: error: "+e.getMessage());
    }
    return super.onCreateOptionsMenu(menu);
}

निम्नलिखित आपके नाम सेटर की गतिविधि होगी। या तो एक बटन क्लिक के माध्यम से या सशर्त कोड के माध्यम से

public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}

इसने मेरे लिए काम किया।


0

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

जब आप ओवरराइड करते हैं और आपकी इस पद्धति का उपयोग करते हैं, तो आप onPrepareOptionsMenu में वैश्विक चर में मेनू का उदाहरण क्यों नहीं लेते हैं। सुनिश्चित करें कि जब भी कोई घटना होती है (जैसे बटन क्लिक), या गतिविधि में यूआई थ्रेड, हैंडलर या एस्कॉन-टास्क पोस्ट-एक्जीक्यूट को कहा जाता है।

आपको इस मेनू आइटम के सूचकांक को पहले से जानना चाहिए जिसे आप बदलना चाहते हैं। मेनू साफ़ करने के बाद, आपको मेनू XML को फुलाकर अपने आइटम का नाम या आइकन अपडेट करना होगा।


0

उन लोगों के लिए जिन्हें शीर्षक की आवश्यकता सांख्यिकीय रूप से है। यह AndroidManifest.xml में किया जा सकता है

<activity
    android:name=".ActivityName"
    android:label="Title Text" >
</activity>

विकल्प मेनू शीर्षक पाठ


3
प्रश्न गतिशील रूप से हैं, न कि सांख्यिकीय रूप से!
इंजनविज़न नोव

अभी भी Google खोज पर आया और मेरी मदद की, पोस्ट करने के लिए धन्यवाद
bruchowski

0

मुझे टुकड़े के लिए मेनू आइकन बदलने की आवश्यकता थी। मैंने इस सवाल के चार्ल्स के जवाब को खंड के लिए थोड़ा बदल दिया:

    private Menu top_menu;

    //...
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

       setHasOptionsMenu(true);
       //...
       rootview = inflater.inflate(R.layout.first_content,null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.fragment_menu, menu);
        this.top_menu = menu;
    }


    // my procedure
    private void updateIconMenu() {
         if(top_menu!= null) {
             MenuItem nav_undo = top_menu.findItem(R.id.action_undo);
             nav_undo.setIcon( R.drawable.back);
         }
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.