Android 如何更改操作栏菜单项';s图标动态

Android 如何更改操作栏菜单项';s图标动态,android,android-actionbar,menuitem,Android,Android Actionbar,Menuitem,我想在收到服务器通知时动态更改菜单项的图标。但是,当更改菜单项图标的代码运行时,我得到了一个NullPointerException 用于更改菜单项图标的代码在onCreationsMenu方法中定义如下: @Override public boolean onCreateOptionsMenu(Menu menu) { // getMenuInflater().inflate(R.menu.main, menu); this.menu = menu; if (

我想在收到服务器通知时动态更改菜单项的图标。但是,当更改菜单项图标的代码运行时,我得到了一个
NullPointerException

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

 @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);
     }
 }
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);
                        }
                    }
                }
            }                   
        }
    });
}
updateCount
方法中,我更改图标如下:

 @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);
     }
 }
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);
                        }
                    }
                }
            }                   
        }
    });
}
这是我的菜单项“通知”文件:


请帮助。

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

if (menu != null) {
    MenuItem item = menu.findItem(R.id.your_menu_action);
    if (item != null) {
        item.setIcon(R.drawable.ic_notification1);
    }
}
更新:基于您的代码,我做了下面的示例,效果很好。您可以使用它作为基础或进行比较,以找出代码不起作用的原因。我不知道
@layout/action\u bar\u notification\u icon
看起来是什么样子,在您的情况下可能会有问题

在本例中,单击菜单项后,
ic\u菜单删除
e将替换为
ic\u菜单编辑

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>
changeIcon()模拟您的updateCount()


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


我也遇到过同样的问题,@Dario answers非常有效,只要你不调用
invalidateOptions菜单()

为了解决这个问题,我将可绘制资源分配给一个变量,并调用
invalidateOptions菜单()
,在这里我要更改图标,并在
onCreateOptions菜单()
中设置图标。代码应如下所示:

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);
}
有3个步骤:

  • 定义一个全局
    MenuItem
    变量
  • oncreateoptions菜单中
    方法指定您的值(目标 菜单)到它
  • 需要时更改图标

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

  • 我实现了你的代码,但它没有改变图标。先生,请告诉我如何更改图标。确保调用了item.setIcon()。如果不是,请检查.menu返回nullIs menuInflater.inflate()的原因。调用该函数后,您将传递正确的资源?使用更新的代码更新您的初始帖子,并附加菜单资源。非常好的解决方案,我的朋友+11+超级经典!
    android:icon="@android:drawable/ic_menu_delete" 
    app:showAsAction="always"
    
    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);
    }
    
     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);
       }
       //...
    }