如何dynamic更改ActionBar菜单项的图标

我想从服务器获取通知时dynamic更改菜单项的图标。 但是,当代码更改菜单项的图标运行时,我得到一个NullPointerException

我用来更改菜单项的图标的代码在onCreatOptionsMenu方法中定义如下:

  @Override public boolean onCreateOptionsMenu(Menu menu) { // getMenuInflater().inflate(R.menu.main, menu); this.menu = menu; if (mDrawerLayout != null && isDrawerOpen()) showGlobalContextActionBar(); MenuInflater menuInflater = this.getMenuInflater(); menuInflater.inflate(R.menu.notification, menu); return super.onCreateOptionsMenu(menu); } } 

并在updateCount方法中,我正在更改图标如下:

 public void updateCount(int count) { hot_count = count; System.out.println("Value of count: " + count); runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub if (hot_count > 0) { if(hot_count>0) { if (menu != null) { MenuItem item = menu.findItem(R.id.menu_hotlist); if (item != null) { item.setIcon(R.drawable.ic_notification1); } } } } } }); } 

这是我的menuitem“通知”文件。

 <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" > <item android:id="@+id/menu_hotlist" android:actionLayout="@layout/action_bar_notification_icon" android:showAsAction="always" android:icon="@drawable/ic_notification" android:title="Notification" /> </menu> 

这是我的logcat:

 01-20 15:03:29.811: E/AndroidRuntime(10318): java.lang.NullPointerException 01-20 15:03:29.811: E/AndroidRuntime(10318): at com.xsinfosol.helpdesk_customer.TAB_Activity$3.run(TAB_Activity.java:294) 01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.Handler.handleCallback(Handler.java:730) 01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.Handler.dispatchMessage(Handler.java:92) 01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.Looper.loop(Looper.java:137) 01-20 15:03:29.811: E/AndroidRuntime(10318): at android.os.HandlerThread.run(HandlerThread.java:61) 01-20 15:04:04.881: I/System.out(11629) 

请帮忙。

Solutions Collecting From Web of "如何dynamic更改ActionBar菜单项的图标"

看起来像menu.getItem(index)返回null,因为菜单没有膨胀(你有检查mDrawerLayout != null && isDrawerOpen() ),或者你可能有不存在的index 。 而不是依靠菜单项索引你可以使用资源ID,也检查为空:

 if (menu != null) { MenuItem item = menu.findItem(R.id.your_menu_action); if (item != null) { item.setIcon(R.drawable.ic_notification1); } } 

更新:根据你的代码,我做了下面的例子,工程。 你可以使用它作为基础或比较,以find你的代码不工作的原因。 我不知道@layout/action_bar_notification_icon如何看起来像你的情况可能是在那里的问题。

在这个例子中,一旦你点击菜单项, ic_menu_edit就被ic_menu_editreplace。

test_menu.xml

 <?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/test_menu_item" android:icon="@android:drawable/ic_menu_delete" android:showAsAction="always" android:title="Item1"/> </menu> 

码:

 private Menu menu; @Override public boolean onCreateOptionsMenu(Menu menu) { this.menu = menu; getMenuInflater().inflate(R.menu.test_menu, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.test_menu_item: changeIcon(); break; default: break; } return super.onOptionsItemSelected(item); } 

changeIcon()模拟你的updateCount()

 public void changeIcon(){ runOnUiThread(new Runnable() { @Override public void run() { if (menu != null) { MenuItem item = menu.findItem(R.id.test_menu_item); if (item != null) { item.setIcon(android.R.drawable.ic_menu_edit); } } } }); } 

我也有同样的问题,只要你不叫invalidateOptionsMenu() ,@Dario的答案就像一个魅力,

为了解决这个问题,我将可绘制的资源分配给一个variables,并调用invalidateOptionsMenu() ,我想要更改图标,并在onCreateOptionsMenu()设置图标。 代码应该是这样的:

 private int drawableResourceId = R.drawable.default_menu_icon; @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.test_menu, menu); menu.findItem(R.id.change_menu_item_icon).setIcon(drawableResourceId); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.change_menu_item_icon: drawableResourceId = R.drawable.changed_menu_icon; invalidateOptionsMenu(); break; default: break; } return super.onOptionsItemSelected(item); } 

我有同样的问题。 请确保您的菜单项中有以下内容(图标和showAsAction设置为始终):

 android:icon="@android:drawable/ic_menu_delete" app:showAsAction="always" 

有3个步骤:

  1. 定义一个全局MenuItemvariables。
  2. onCreateOptionsMenu方法分配你的价值(目标菜单)。
  3. 改变图标。

      public class NotificationActivity extends BaseActivity { //#1 Menu globalMenuItem; //other variables @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.notification_menu, menu); //#2 globalMenuItem= menu.add(Menu.NONE,menuId, Menu.NONE, title); globalMenuItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_ALWAYS) .setIcon(R.drawable.notification_icon_1); //other menu items } //#3 private void changeIcon(){ flashMenuItem.setIcon(R.drawable.notification_icon_2); } //... } 

    希望能帮助到你 。