How to change menu item text dynamically in Android
I'm trying to change the title of a menu item from outside of the onOptionsItemSelected(MenuItem item)
method.
I already do the following;
public boolean onOptionsItemSelected(MenuItem item) {
try {
switch(item.getItemId()) {
case R.id.bedSwitch:
if(item.getTitle().equals("S开发者_如何转开发et 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;
}
however I'd like to be able to modify the title of a particular menu item outside of this method.
I would suggest keeping a reference within the activity to the Menu object you receive in onCreateOptionsMenu and then using that to retrieve the MenuItem that requires the change as and when you need it. For example, you could do something along the lines of the following:
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);
}
}
}
Alternatively, you can override onPrepareOptionsMenu to update the menu items each time the menu is displayed.
As JxDarkAngel suggested, calling this from anywhere in your Activity,
invalidateOptionsMenu();
and then overriding:
@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);
}
is a much better choice. I used the answer from https://stackoverflow.com/a/17496503/568197
you can do this create a global "Menu" object then assign it in onCreateOptionMenu
public class ExampleActivity extends AppCompatActivity
Menu menu;
then assign here
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
this.menu = menu;
return true;
}
Then later use assigned Menu object to get required items
menu.findItem(R.id.bedSwitch).setTitle("Your Text");
Create a setOptionsTitle() method and set a field in your class. Such as:
String bedStatus = "Set to 'Out of Bed'";
...
public void setOptionsTitle(String status)
{
bedStatus = status;
}
Now when the menu gets populated, change the title to whatever your status is:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(bedStatus);
// Return true so that the menu gets displayed.
return true;
}
You better use the override 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");
}
Here an example
I use this code to costum my bottom navigation item
BottomNavigationView navigation = this.findViewById(R.id.my_bottom_navigation);
Menu menu = navigation.getMenu();
menu.findItem(R.id.nav_wall_see).setTitle("Hello");
Declare your menu field.
private Menu menu;
Following is onCreateOptionsMenu() method
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);
}
Following will be your name setter activity. Either through a button click or through conditional code
public void setMenuName(){
menu.findItem(R.id.menuItemId).setTitle(/*Set your desired menu title here*/);
}
This worked for me.
You can do it like this, and no need to dedicate variable:
Toolbar toolbar = findViewById(R.id.toolbar);
Menu menu = toolbar.getMenu();
MenuItem menuItem = menu.findItem(R.id.some_action);
menuItem.setTitle("New title");
Or a little simplified:
MenuItem menuItem = ((Toolbar)findViewById(R.id.toolbar)).getMenu().findItem(R.id.some_action);
menuItem.setTitle("New title");
It works only - after the menu created.
You can Change Menu Item text using below Code: -
fun showPopup(v: View) {
popup = PopupMenu(context, v)
val inflater = popup?.menuInflater
popup?.setOnMenuItemClickListener(this)
inflater?.inflate(R.menu.menu_main, popup?.menu)
val menu: Menu = popup!!.menu
val item = menu.findItem(R.id.name)
if (item.title.equals("Name")) {
item.title = "Safal Bhatia"
}
}
It seems to me that you want to change the contents of menu inside a local method, and this method is called at any time, whenever an event is occurred, or in the activity UI thread.
Why don't you take the instance of Menu in the global variable in onPrepareOptionsMenu when this is overridden and use in this method of yours. Be sure that this method is called whenever an event is occurred (like button click), or in the activity UI thread, handler or async-task post-execute.
You should know in advance the index of this menu item you want to change. After clearing the menu, you need to inflate the menu XML and update your item's name or icon.
For people that need the title set statically. This can be done in the AndroidManifest.xml
<activity
android:name=".ActivityName"
android:label="Title Text" >
</activity>
I needed to change the menu icon for the fragment. I altered Charles’s answer to this question a bit for the fragment:
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);
}
}
I hit this problem too. In my case I wanted to set the string to reflect additional information using getString.
As stated above you need to find the correct menuItem in the menu and set it in the onPrepareOptionsMenu method. The solutions above didn't handle the case where the item was in a sub menu and for this you need to search the submenu for the item. I wrote a little Kotlin recursive function to allow me to this for multiple items. Code below...
override fun onPrepareOptionsMenu(menu: Menu) {
...
menu.menuSetText(R.id.add_new_card,
getString(R.string.add_card, currentDeck.deckName))
...
}
private fun Menu.getMenuItem(idx: Int, itemId: Int): MenuItem? {
Log.d(TAG, "getMenuItem: $idx of ${this.size()}")
if (idx >= size()) return null
val item = getItem(idx)
if (item.hasSubMenu()) {
val mi = item.subMenu.getMenuItem(0, itemId)
// mi non-null means we found item.
if (mi != null)
return mi
}
if (item != null && item.itemId == itemId)
return item
return getMenuItem(idx + 1, itemId)
}
fun Menu.menuSetText(itemId: Int, title: String) {
val menuItem = getMenuItem(0, itemId)
if (menuItem != null)
menuItem.title = title
else
Log.e(TAG,
"menuSetText to \"$title\": Failed to find ${
"itemId:0x%08x".format(itemId)}"
)
}
精彩评论