如何动态更改ActionBar菜单项的图标

时间:2015-01-20 09:44:20

标签: android android-actionbar menuitem

我希望在收到服务器通知时动态更改菜单项的图标。但是,当更改菜单项图标的代码运行时,我收到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)

请帮忙。

4 个答案:

答案 0 :(得分:9)

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

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

更新:根据您的代码我做了下面的例子。您可以将其用作基础或进行比较,以查找代码无法正常工作的原因。我不知道@layout/action_bar_notification_icon是怎样的,所以在你的情况下可能会有问题。

在此示例中,单击菜单项后,ic_menu_delet e将替换为ic_menu_edit

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

答案 1 :(得分:4)

我也有同样的问题,只要你不打电话{@ 1}},@ Dario的答案就像魅力一样

要解决此问题,我将drawable资源分配给变量并调用invalidateOptionsMenu()我要更改图标的位置,然后在invalidateOptionsMenu()中设置图标。代码应该是这样的:

onCreateOptionsMenu()

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

有3个步骤:

  1. 定义全局MenuItem变量。
  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  call this when required
       private void changeIcon(){
           globalMenuItem.setIcon(R.drawable.notification_icon_2);
       }
       //...
    }